将图像上传到 Google 驱动器以进行 OCR

Upload image to Google Drive for OCR

我正在尝试将图像上传到 Google 光字符识别 (OCR) 驱动器。这是我的代码:

require_once('vendor/autoload.php');

// Initialize Google Client
$client_email = 'xxxxxx@yyyyy.iam.gserviceaccount.com';
$private_key = file_get_contents('key.p12');
$scopes = array(
    'https://www.googleapis.com/auth/drive.file'
);
$credentials = new Google_Auth_AssertionCredentials(
    $client_email,
    $scopes,
    $private_key
);
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
  $client->getAuth()->refreshTokenWithAssertion();
}

// Initialize Google Drive service
$service = new Google_Service_Drive($client);

// Upload File
$file = new Google_Service_Drive_DriveFile();
$file->setName('Test Image for OCR');
$file->setDescription('Test Image for OCR');
$file->setMimeType('image/jpeg');
try {
  $data = file_get_contents($filename);
  $createdFile = $service->files->create($file, array(
      'data' => $data,
      'mimeType' => 'image/jpeg',
  ));
  var_dump($createdFile);
  // ===========
  // So, what's next?
  // ===========
} catch(Exception $e) {
  echo 'Error occurred: ' . $e->getMessage();
}

以上代码运行没有错误,$createdFileGoogle_Service_Drive_DriveFile对象形式的有效资源。

问题:

  1. 估计上传成功了,因为create()函数没有return报错。但是,我在 Google 驱动器中看不到上传的文件。不应该上传到 Google 驱动器的根文件夹吗?

  2. 如何执行 OCR?我可以从 here 中读到有一个名为 ocrLanguage 的参数。我应该把它放在哪里以及如何获得结果?

提前致谢。

UPDATE var_dump() 结果如下:

object(Google_Service_Drive_DriveFile)#18 (55) {
  ["collection_key":protected]=>
  string(6) "spaces"
  ["internal_gapi_mappings":protected]=>
  array(0) {
  }
  ["appProperties"]=>
  NULL
  ["capabilitiesType":protected]=>
  string(42) "Google_Service_Drive_DriveFileCapabilities"
  ["capabilitiesDataType":protected]=>
  string(0) ""
  ["contentHintsType":protected]=>
  string(42) "Google_Service_Drive_DriveFileContentHints"
  ["contentHintsDataType":protected]=>
  string(0) ""
  ["createdTime"]=>
  NULL
  ["description"]=>
  NULL
  ["explicitlyTrashed"]=>
  NULL
  ["fileExtension"]=>
  NULL
  ["folderColorRgb"]=>
  NULL
  ["fullFileExtension"]=>
  NULL
  ["headRevisionId"]=>
  NULL
  ["iconLink"]=>
  NULL
  ["id"]=>
  string(28) "0B_XXXXX1yjq7dENaQWp4ckZoRk0"
  ["imageMediaMetadataType":protected]=>
  string(48) "Google_Service_Drive_DriveFileImageMediaMetadata"
  ["imageMediaMetadataDataType":protected]=>
  string(0) ""
  ["kind"]=>
  string(10) "drive#file"
  ["lastModifyingUserType":protected]=>
  string(25) "Google_Service_Drive_User"
  ["lastModifyingUserDataType":protected]=>
  string(0) ""
  ["md5Checksum"]=>
  NULL
  ["mimeType"]=>
  string(10) "image/jpeg"
  ["modifiedByMeTime"]=>
  NULL
  ["modifiedTime"]=>
  NULL
  ["name"]=>
  string(18) "Test Image for OCR"
  ["originalFilename"]=>
  NULL
  ["ownedByMe"]=>
  NULL
  ["ownersType":protected]=>
  string(25) "Google_Service_Drive_User"
  ["ownersDataType":protected]=>
  string(5) "array"
  ["parents"]=>
  NULL
  ["permissionsType":protected]=>
  string(31) "Google_Service_Drive_Permission"
  ["permissionsDataType":protected]=>
  string(5) "array"
  ["properties"]=>
  NULL
  ["quotaBytesUsed"]=>
  NULL
  ["shared"]=>
  NULL
  ["sharedWithMeTime"]=>
  NULL
  ["sharingUserType":protected]=>
  string(25) "Google_Service_Drive_User"
  ["sharingUserDataType":protected]=>
  string(0) ""
  ["size"]=>
  NULL
  ["spaces"]=>
  NULL
  ["starred"]=>
  NULL
  ["thumbnailLink"]=>
  NULL
  ["trashed"]=>
  NULL
  ["version"]=>
  NULL
  ["videoMediaMetadataType":protected]=>
  string(48) "Google_Service_Drive_DriveFileVideoMediaMetadata"
  ["videoMediaMetadataDataType":protected]=>
  string(0) ""
  ["viewedByMe"]=>
  NULL
  ["viewedByMeTime"]=>
  NULL
  ["viewersCanCopyContent"]=>
  NULL
  ["webContentLink"]=>
  NULL
  ["webViewLink"]=>
  NULL
  ["writersCanShare"]=>
  NULL
  ["modelData":protected]=>
  array(0) {
  }
  ["processed":protected]=>
  array(0) {
  }
}

该文件可以通过 $service->files->get($file_id); 获取,但在我的 Google 驱动器中不可见。文件资源对象 returned 也不包含任何有用的内容。

服务帐户不是您,它更像是一个虚拟用户。它有自己的驱动器帐户。

如果您想上传到您的个人帐户。获取服务帐户电子邮件地址并将其共享到您的个人驱动器帐户中的一个目录中。就像您想与之共享目录或文件的任何其他用户一样。

然后您需要找出目录 ID,我发现这样做的唯一方法是让服务帐户执行 files.list 以获取它现在可以访问的所有内容的列表。找到目录 ID 或父 ID 后 您可以将上面的代码更改为

'data' => $data,
'mimeType' => 'image/jpeg',
'parents'   => 'the directory id'

从代码的外观来看,我认为您使用的是 V3 api 我还没有时间使用它。 'parents' => 'the directory id' <-- 这是一个有根据的猜测。如果它不起作用,请告诉我,我会 google 花点时间弄清楚如何将 parent 传递给 v3。

选项编号 2:

另一个选项是让服务帐户与您共享其文件夹,然后您将有权访问其云端硬盘帐户,并且您将能够在您的网络版云端硬盘中看到该文件夹​​。再次搜索权限 我认为您使用的是 V3 我还没有看过。不同之处在于数据的存储位置以及存储的计算对象。

不要使用服务帐户。如果你想上传到你自己的账户,那么你只需要为你的账户获取一个合适的访问令牌。使用共享文件夹的中间帐户真的很难看(恕我直言)。

我刚刚在V3中找到了OCR的方法。

  1. 上传图片
  2. 使用 mimeType 将图像复制到 Google 文档 "application/vnd.google-apps.document"
  3. 使用 mimeType 将文档导出为纯文本 "text/plain"

P.S。似乎第 2 步不适用于 "appDataFolder".

UserCredential credential = null;
try
{
    credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
        new Uri("ms-appx:///Assets/client_secret.json"), 
        new[] { DriveService.Scope.DriveFile }, "user", CancellationToken.None);
}
catch (AggregateException ex)
{
    Debug.Write("Credential failed, " + ex.Message);
}

// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = "TestApp",
});

// Create folder
var folderMetadata = new Google.Apis.Drive.v3.Data.File();
folderMetadata.Name = "NewFolder";
folderMetadata.MimeType = "application/vnd.google-apps.folder";
var request = service.Files.Create(folderMetadata);
request.Fields = "id";
var folder = request.Execute();
Debug.WriteLine("Folder ID: " + folder.Id);

// Upload the image file
var fileMetadata = new Google.Apis.Drive.v3.Data.File();
fileMetadata.Name = inputFile.Name;
fileMetadata.Parents = new List<string> { folder.Id };
FilesResource.CreateMediaUpload requestUpload;
using (var stream = new System.IO.FileStream(inputFile.Path, System.IO.FileMode.Open))
{
    requestUpload = service.Files.Create(fileMetadata, stream, "image/jpeg");
    requestUpload.Fields = "id";
    requestUpload.Upload();
}
var imgFile = requestUpload.ResponseBody;
Debug.WriteLine("File ID: " + imgFile.Id);

// Copy image and paste as document
var textMetadata = new Google.Apis.Drive.v3.Data.File();
textMetadata.Name = inputFile.Name;
textMetadata.Parents = new List<string> { folderId };
textMetadata.MimeType = "application/vnd.google-apps.document";
FilesResource.CopyRequest requestCopy = service.Files.Copy(textMetadata, imgFile.Id);
requestCopy.Fields = "id";
requestCopy.OcrLanguage = "zh";
var textFile = requestCopy.Execute();

// Now we export document as plain text
FilesResource.ExportRequest requestExport = service.Files.Export(textFile.Id, "text/plain");
string output = requestExport.Execute();