在Google App Engine中存储旋转/翻转的图像 [英] Storing rotated / flipped images in Google App Engine

查看:101
本文介绍了在Google App Engine中存储旋转/翻转的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是blobkey:

我试图旋转/翻转已存在于Google Cloud Storage中的图片。

  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,我可以将它写入云存储服务:

  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:

pre $ BlobstoreService blobstoreService = BlobstoreServiceFactory。 getBlobstoreService();
地图< 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方法中,我执行以下操作:

pre $ 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: p>


encoded_gs_key:L2dzL2F1Y3Rpb24tcG9ydGFsLXVwbG9hZHMvZmFrZS1lbmNvZGVkX2dzX2tleTpZWFZqZEdsdmJpMXdiM0owWVd3dGRYQnNiMkZrY3k4NFNYcDVWR3BJVVdsWlNEWTVYMVl0Y2s1VGJHdFItMGY5NjlmNWI0ZjUzYTAxNDc5ZmYyZDVlYWYwMmZhMWE




当我尝试:

  imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(bk); 

现在我得到一个 INVALID_BLOB_KEY:无法读取blob。

与:

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

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 / < stdout> ;: fileName.getBucketName():bucket-name

  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:AMIfv94Tj3xO9hPWwMm314IdOobQs1gVWOHYVuGaaAjjMbieBUD6x0nNGbqiY8o5Jk9iLga4pPe9-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 ...

当我访问这些我收到的所有网址都是原始图片。



当我查看Cloud Storage Dashboard时,原始图片位于:
首页/存储区/ b>

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



因此它不会覆盖原文。
我猜想我创建的fileName不正确,或者我创建的GcsOutputChannel正在改变路径?
我也很好奇为什么我要获取原始图片的网址而不是新图片的网址?



如果我将原始GcsFileName分开,最后一部分,我收到一个错误:

pre $ g code> GcsFilename fileName = new GcsFilename(bucket-name,upload.getGcsFileName( ).split( /)[3]);

Google存储文件名必须以/ gs /

为前缀

任何想法?

解决方案

Retreive blobKey using:

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

...即使fileName.getObjectName()已包含/ gs / bucket-name /在对象名前面。当将它打印到标准输出时,您的fileName应该包含/ gs / bucket-name /两次,很奇怪,但是它可以工作。使用该blobKey,正确的服务URL是创建

解决方案

要覆盖原始图像,您只需指定相同的云存储文件名即可。 b

据我所知,您已通过App Engine通过BlobStore API将图像上传到云端存储。要获取原始图像的实际文件名,您必须在上传servlet中添加以下代码

 映射<字符串,列表< BlobInfo>> uploadInfos = getFileInfos(httpServletRequest); 
String theGCSFilename = uploadInfos.get(yourFileName)。getGsObjectName();

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


  • 像这样使用ImageService:

      ImagesService imagesService = ImagesServiceFactory.getImagesService(); 
    String url = imagesService.getServingUrl(ServingUrlOptions.Builder.withGoogleStorageFileName(java));


  • 创建一个自定义 GCSServingServlet 将使用 BlobstoreService.serve()方法来提供来自Blobstore或云端存储的文件。在这种情况下,您必须自己检查权限。请注意,您可以使用 BlobStoreService.createGSBlobKey()从 GCSFilename 创建 BlobKey code>。


  • 使用云端存储伺服网址:



I'm trying to rotate / flip an image that is already sitting inside Google Cloud Storage.

This is the blobkey:

BlobKey blobKey = new BlobKey(upload.getBlobKey());

Then I retrieve the image and apply an image transform:

ImagesService imagesService = ImagesServiceFactory.getImagesService();
Image image = ImagesServiceFactory.makeImageFromBlob(blobKey);
Transform transform = ImagesServiceFactory.makeRotate(90);
Image newImage = imagesService.applyTransform(transform, image);

The RAW image data I can get in a byte array using:

newImage.getImageData()

Using GCS directly, I can write it to the cloud storage service:

GcsFilename fileName = new GcsFilename("bucket-name", upload.getFileName());
GcsOutputChannel outputChannel = GcsServiceFactory.createGcsService().createOrReplace(fileName, GcsFileOptions.getDefaultInstance());
outputChannel.write(ByteBuffer.wrap(newImage.getImageData()));
outputChannel.close();

Locally I can see the rotated image sitting inside the appengine-generated folder, how do I get the new serving url or what should the objectName be in order to overwrite the original image? Is the objectName the same as the original filename when it was uploaded, is it the blobkey, ...?

Update:

I'm storing the GcsFilename upon upload:

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();

The GcsFileName looks like this (locally):

/gs/bucket-name/fake-encoded_gs_key:YXVjdGlvbi1wb3J0YWwtdXBsb2Fkcy84SXp5VGpIUWlZSDY5X1Ytck5TbGtR-0f969f5b4f53a01479ff2d5eaf02fa1a (unindexed)

Then inside my rotate method, I do the following:

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());

When I print the new blobKey using bk.getKeyString(), I get an enormous blobkey:

encoded_gs_key:L2dzL2F1Y3Rpb24tcG9ydGFsLXVwbG9hZHMvZmFrZS1lbmNvZGVkX2dzX2tleTpZWFZqZEdsdmJpMXdiM0owWVd3dGRYQnNiMkZrY3k4NFNYcDVWR3BJVVdsWlNEWTVYMVl0Y2s1VGJHdFItMGY5NjlmNWI0ZjUzYTAxNDc5ZmYyZDVlYWYwMmZhMWE

When I try:

imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(bk);

I now get a INVALID_BLOB_KEY: Could not read blob.

Same with:

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

INVALID_BLOB_KEY: Could not read blob.

Update - Testing On Live:

I've done some logging on live to see if I can pinpoint where things are going wrong.

When I print out the GcsFilename, this is what I'm getting:

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

Then generating the new 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

Then using 3 different methods for getting the new serving urls:

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

When I access these URLs, all I'm getting is the original image.

When I look in the Cloud Storage Dashboard, the original image is sitting in: Home/bucket-name/

The rotated image however is sitting in: Home/bucket-name//gs/bucket-name/

Hence the reason it's not overwriting the original. I'm guessing either the fileName I'm creating is incorrect or the GcsOutputChannel I'm creating is changing the path? I'm also curious why I'm getting the original image's url instead of the new image's url?

If I split the original GcsFileName and only take the last part, I'm getting an error:

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

Google storage filenames must be prefixed with /gs/

Any ideas?

Solution

Retreive blobKey using:

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

... even though fileName.getObjectName() already contains "/gs/bucket-name/" in front of the objectname. When printing it to standard out, your fileName should contain /gs/bucket-name/ twice, weird, but it works.

Using that blobKey, the correct serving URL is created

解决方案

To override the original image, you simply need to specify the same Cloud Storage filename.

I understand that you have uploaded the image to Cloud Storage through App Engine via the BlobStore API. To get the actual filename of the original image, you must add the following code in the upload servlet :

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

Note that if you do not want to overwrite the original file, but want to provide a serving URL to the customer, you can either :

  • Use the ImageService like this :

    ImagesService imagesService = ImagesServiceFactory.getImagesService();
    String url = imagesService.getServingUrl(ServingUrlOptions.Builder.withGoogleStorageFileName(java));
    

  • Create a custom GCSServingServlet who will use the BlobstoreService.serve() method to serve a file from the Blobstore or Cloud Storage. In that case, you must check the permissions yourself. Note that you can create a BlobKey from a GCSFilename using BlobStoreService.createGSBlobKey().

  • Use the Cloud Storage serving URLs :

这篇关于在Google App Engine中存储旋转/翻转的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆