我正在尝试将图像上传到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();
}
上述代码运行没有错误,并且$createdFile
是对象形式的有效资源Google_Service_Drive_DriveFile
。
问题:
我想上传成功,因为
create()
函数不返回错误。但是,我看不到文件已上传到我的Google云端硬盘中。它不应该上传到谷歌云端硬盘的根文件夹吗?如何执行 OCR?我可以从这里读到有一个名为
ocrLanguage
的参数。我应该把它放在哪里,我如何获得结果?
提前谢谢。
更新 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云端硬盘中是不可见的。返回的文件资源对象也不包含任何有用的内容。
我刚刚在 V3 中找到了 OCR 的方法。
- 上传图片
- 使用 mimeType "application/vnd.google-apps.document" 将图像复制到 Google 文档
- 使用 mimeType "text/plain" 将文档导出为纯文本
附言似乎步骤 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();
服务帐户不是你,它更像是一个虚拟用户。 它有自己的驱动器帐户。
如果您想上传到您的个人帐户。 获取服务帐号电子邮件地址,并将其共享到您的个人云端硬盘帐号中的目录。 就像您要与之共享目录或文件的任何其他用户一样。
然后,您需要找出目录 id,我发现这样做的唯一方法是让服务帐户执行 files.list 以获取它现在有权访问的所有内容的列表。 找到目录 ID 或父 ID 后您可以将上面的代码更改为类似
'data' => $data,
'mimeType' => 'image/jpeg',
'parents' => 'the directory id'
我认为从您的代码外观来看,您正在使用 V3 api,我没有时间使用它。 'parents' => 'the directory id'
<--这是一个有根据的猜测。 如果它不起作用,请告诉我,我会谷歌一下以弄清楚如何将父级传递给 v3。
选项 2:
另一种选择是让服务帐号与您共享其文件夹,然后您就可以访问其云端硬盘帐号,并且您将能够在网络版云端硬盘中看到该文件夹。 再次搜索权限我认为您正在使用V3,我还没有看过。 区别在于数据的存储位置以及存储的计数对象。
不要使用服务帐户。如果要上传到自己的帐户,则只需为您的帐户获取适当的访问令牌即可。使用共享文件夹的中间帐户真的很丑陋(恕我直言)。