首页 文章

在Google App Engine中存储旋转/翻转的图像

提问于
浏览
8

我正在尝试旋转/翻转已经位于Google Cloud 端存储中的图像 .

这是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图像数据:

newImage.getImageData()

直接使用GCS,我可以将其写入 Cloud 存储服务:

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,......?

Update:

我在上传时存储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(未编入索引)

然后在我的rotate方法中,我执行以下操作:

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: Could not read blob.

与:相同:

imagesService.getServingUrl(ServingUrlOptions.Builder.withGoogleStorageFileName(fileName.getObjectName()));

INVALID_BLOB_KEY: Could not read blob.

Update - Testing On Live:

我已经做了一些现场登录,看看我是否可以找出出错的地方 .

当我打印出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种不同的方法获取新的服务URL:

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时,我得到的只是原始图像 .

当我查看Cloud Storage Dashboard时,原始图像位于:Home / bucket-name /

然而,旋转的图像位于:Home / bucket-name // gs / bucket-name /

因此它不会覆盖原始的原因 . 我猜我正在创建的fileName是不正确的还是我正在创建的GcsOutputChannel正在改变路径?我也很好奇为什么我得到原始图片的网址而不是新图片的网址?

如果我拆分原始的GcsFileName并只取最后一部分,我收到一个错误:

GcsFilename fileName = new GcsFilename("bucket-name", upload.getGcsFileName().split("/")[3]);

Google存储文件名必须以/ gs /为前缀

有任何想法吗?

Solution

Retreive blobKey使用:

BlobKey blobKey = blobstoreService.createGsBlobKey("/gs/" + fileName.getBucketName() + "/" + fileName.getObjectName());

...即使fileName.getObjectName()已在对象名前面包含“/ gs / bucket-name /” . 将它打印到标准输出时,你的fileName应该包含/ gs / bucket-name /两次,很奇怪,但是它有效 .

使用该blobKey,将创建正确的服务URL

1 回答

  • 3

    要覆盖原始映像,只需指定相同的 Cloud 存储文件名即可 .

    我了解您已通过App Engine通过BlobStore API将映像上传到 Cloud 存储 . 要获取原始图像的实际文件名,必须添加以下代码 in the upload servlet :

    Map<String,List<BlobInfo>> uploadInfos = getFileInfos(httpServletRequest);
      String theGCSFilename = uploadInfos.get("yourFileName").getGsObjectName();
    

    请注意,如果您不想覆盖原始文件,但想要向客户提供服务URL,您可以:

    • 像这样使用ImageService:
    ImagesService imagesService = ImagesServiceFactory.getImagesService();
    String url = imagesService.getServingUrl(ServingUrlOptions.Builder.withGoogleStorageFileName(java));
    

相关问题