我想旋转/翻转已经坐在Google云端存储中的图像。在Google App Engine中存储旋转/翻转的图像
这是的BlobKey:
BlobKey blobKey = new BlobKey(upload.getBlobKey());
然后我检索图像和应用图像变换:
ImagesService imagesService = ImagesServiceFactory.getImagesService();
Image image = ImagesServiceFactory.makeImageFromBlob(blobKey);
Transform transform = ImagesServiceFactory.makeRotate(90);
Image newImage = imagesService.applyTransform(transform, image);
的RAW图像数据I可以以字节数组得到使用:
newImage.getImageData()
直接使用GCS,我可以将它写入云存储服务:
GcsFilename fileName = new GcsFilename("bucket-name", upload.getFileName());
GcsOutputChannel outputChannel = GcsServiceFactory.createGcsService().createOrReplace(fileName, GcsFileOptions.getDefaultInstance());
outputChannel.write(ByteBuffer.wrap(newImage.getImageData()));
outputChannel.close();
本地我可以看到坐在appengine生成的文件夹中的旋转图像,我如何获得新的服务url或objectName是为了覆盖原始图像? objectName与上传时的原始文件名相同,是blobkey,...?
更新:
我存储在上载的GcsFilename:
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Map<String,List<FileInfo>> finfos = blobstoreService.getFileInfos(req);
String gcsFileName = finfos.get("uploadKey").get(0).getGsObjectName();
upload.setGcsFileName(gcsFileName);
upload.persist();
的GcsFileName看起来是这样的(本地):
/gs/bucket-name/fake-encoded_gs_key:YXVjdGlvbi1wb3J0YWwtdXBsb2Fkcy84SXp5VGpIUWlZSDY5X1Ytck5TbGtR-0f969f5b4f53a01479ff2d5eaf02fa1a (unindexed)
然后在我的旋转方式,我做了以下:
GcsFilename fileName = new GcsFilename("bucket-name", upload.getGcsFileName());
GcsOutputChannel outputChannel = GcsServiceFactory.createGcsService().createOrReplace(fileName, GcsFileOptions.getDefaultInstance());
outputChannel.write(ByteBuffer.wrap(newImage.getImageData()));
outputChannel.close();
BlobstoreService bs = BlobstoreServiceFactory.getBlobstoreService();
BlobKey bk = bs.createGsBlobKey(fileName.getObjectName());
当我打印使用bk.getKeyString()新的blobKey,我得到一个巨大的BlobKey:
encoded_gs_key:L2dzL2F1Y3Rpb24tcG9ydGFsLXVwbG9hZHMvZmFrZS1lbmNvZGVkX2dzX2tleTpZWFZqZEdsdmJpMXdiM0owWVd3dGRYQnNiMkZrY3k4NFNYcDVWR3BJVVdsWlNEWTVYMVl0Y2s1VGJHdFItMGY5NjlmNWI0ZjUzYTAxNDc5ZmYyZDVlYWYwMmZhMWE
当我尝试:
imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(bk);
我现在得到INVALID_BLOB_KEY:无法读blob。
与相同:
imagesService.getServingUrl(ServingUrlOptions.Builder.withGoogleStorageFileName(fileName.getObjectName()));
INVALID_BLOB_KEY:无法读取BLOB。
更新 - 测试直播:
我已经做了一些现场记录到看能不能找准事情会出错。
当我打印出来的GcsFilename,这就是我得到:
GcsFilename fileName = new GcsFilename("bucket-name", upload.getGcsFileName());
System.out.println("fileName.getObjectName(): " + fileName.getObjectName());
System.out.println("fileName.getBucketName(): " + fileName.getBucketName());
2014-03-08 09:31:35.076 [s~_____/live-1-0-2.374269833496060124].<stdout>: fileName.getObjectName(): /gs/bucket-name/L2FwcGhvc3RpbmdfcHJvZC9ibG9icy9BRW5CMlI
2014-03-08 09:31:35.076 [s~_____/live-1-0-2.374269833496060124].<stdout>: fileName.getBucketName(): bucket-name
然后产生新的BlobKey:
BlobstoreService bs = BlobstoreServiceFactory.getBlobstoreService();
BlobKey bk = bs.createGsBlobKey(fileName.getObjectName());
System.out.println("GSBlobKey: " + bk.getKeyString());
2014-03-08 09:31:37.993 [s~_____/live-1-0-2.374269833496060124].<stdout>: GSBlobKey: AMIfv94Tj3xO9hPWwMm314Id0obQs1gVWOHYVuGaaAjjMbieBUD6x0nNGbqiY8o5Jk9iLga4pPe9-8L1
然后利用获取新服务的网址3种不同的方法:
String newImageUrl1 = imagesService.getServingUrl(ServingUrlOptions.Builder.withGoogleStorageFileName(fileName.getObjectName()));
System.out.println("newImageUrl1: " + newImageUrl1);
String newImageUrl2 = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(bk));
System.out.println("newImageUrl2: " + newImageUrl2);
String newImageUrl3 = imagesService.getServingUrl(bk);
System.out.println("newImageUrl3: " + newImageUrl3);
2014-03-08 09:31:38.116 [s~_____/live-1-0-2.374269833496060124].<stdout>: newImageUrl1: http://lh3.ggpht.com/My7zTT79xOltI3cMzHidx7-Us91Qlp13jdv-vJceQ_OpX3FONSr9YzI2...
2014-03-08 09:31:38.152 [s~_____/live-1-0-2.374269833496060124].<stdout>: newImageUrl2: http://lh3.ggpht.com/My7zTT79xOltI3cMzHidx7-Us91Qlp13jdv-vJceQ_OpX3FONSr9YzI2...
2014-03-08 09:31:38.218 [s~_____/live-1-0-2.374269833496060124].<stdout>: newImageUrl3: http://lh3.ggpht.com/My7zTT79xOltI3cMzHidx7-Us91Qlp13jdv-vJceQ_OpX3FONSr9YzI2...
当我访问这些URL时,我得到的是原始图像。
当我看着云存储控制台,将原始图像坐在: 主页/桶名称/
旋转后的图像却是坐在: 主页/桶名// GS /桶-name/
因此,它不覆盖原来的原因。 我猜我要创建的fileName不正确,或者我创建的GcsOutputChannel正在改变路径? 我也很好奇为什么我要获取原始图片的网址而不是新图片的网址?
如果我分裂原GcsFileName,只需要最后一部分,我得到一个错误:
GcsFilename fileName = new GcsFilename("bucket-name", upload.getGcsFileName().split("/")[3]);
谷歌存储文件名必须与/ GS前缀/
任何想法?
解决方案
Retreive的blobKey使用:
BlobKey blobKey = blobstoreService.createGsBlobKey("/gs/" + fileName.getBucketName() + "/" + fileName.getObjectName());
...即使fileName.getObjectName()已经包含了 “/ GS /桶名称/” 的对象名的前面。当把它打印到标准输出时,你的fileName应该包含/ gs/bucket-name /两次,很奇怪,但是它可以工作。
使用的blobKey,正确的服务URL创建
嘿月从 “假encoded_gs_key” 我明白,你是在本地开发服务器上进行测试。某些GCS和ImageService功能在此处不可用。 您是否对GAE生产应用程序进行过相同的测试? – David
旋转的图像正在写入不正确的位置,如果我可以修复,那么旋转将是100%,我已经更新了这个问题。 –
Hey Jan,“getObjectName()”不应该返回bucket名称,也不应该在开始时返回“/ gs”。你确定你的日志输出的是对象名称而不是toString()方法的结果吗? – David