Armazenamento de imagens giradas / invertidas no Google App Engine

Estou tentando girar / inverter uma imagem que já está dentro do Google Cloud Storage.

Este é o blobkey:

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

Então, recupero a imagem e aplico uma transformação de imagem:

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

Os dados de imagem RAW que posso obter em uma matriz de bytes usando:

newImage.getImageData()

Usando o GCS diretamente, posso gravá-lo no serviço de armazenamento em nuvem:

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

Localmente, vejo a imagem girada dentro da pasta gerada pelo aplicativo, como obtenho o novo URL de veiculação ou qual deve ser o nome do objeto para substituir a imagem original? O objectName é igual ao nome do arquivo original quando foi carregado, é o blobkey, ...?

Atualizar:

Estou armazenando o GcsFilename após o 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();

O GcsFileName se parece com este (localmente):

/ gs / bucket-name / fake-encoded_gs_key: YXVjdGlvbi1wb3J0YWwtdXBsb2Fkcy84SXp5VGpIUWlZSDY5X1Ytck5TbGtR-0f969f5b4f53a01479ff2d5eaf02fa1

Em seguida, dentro do meu método de rotação, faço o seguinte:

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

Quando imprimo o novo blobKey usando bk.getKeyString (), recebo um enorme blobkey:

encoded_gs_key: L2dzL2F1Y3Rpb24tcG9ydGFsLXVwbG9hZHMvZmFrZS1lbmNvZGVkX2dzX2tleTpZWFZqZEdsdmJpMXdiM0owWVd3dGRYQnNiMkZrY3k4NFNYcDVWR3BJVVdsWlNEWTVYMVl0Y2s1VGJHdFItMGY5NjlmNWI0ZjUzYTAxNDc5ZmYyZDVlYWYwMmZhMWE

Quando tento:

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

Agora eu recebo umINVALID_BLOB_KEY: Não foi possível ler o blob.

Mesmo com:

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

INVALID_BLOB_KEY: Não foi possível ler o blob.

Atualização - Teste no Live:

Eu fiz alguns logins ao vivo para ver se consigo identificar onde as coisas estão dando errado.

Quando imprimo o GcsFilename, é isso que estou recebendo:

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

Em seguida, gerando o novo 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

Em seguida, use três métodos diferentes para obter os novos URLs de veiculação:

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("new,ImageUrl3: " + 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...

Quando acesso esses URLs, tudo o que recebo é a imagem original.

Quando olho no Cloud Storage Dashboard, a imagem original está em: Página inicial / bucket-name /

A imagem girada, no entanto, está em: Página inicial / bucket-name // gs / bucket-name /

Daí a razão pela qual não está substituindo o original. Acho que o fileName que estou criando está incorreto ou o GcsOutputChannel que estou criando está mudando o caminho? Também estou curioso para saber por que estou recebendo o URL da imagem original em vez do URL da nova imagem?

Se eu dividir o GcsFileName original e apenas participar da última parte, estou recebendo um erro:

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

Os nomes de arquivos de armazenamento do Google devem ser prefixados com / gs /

Alguma ideia?

Solução

Recuperar blobKey usando:

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

... embora fileName.getObjectName () já contenha "/ gs / bucket-name /" na frente do nome do objeto. Ao imprimi-lo com o padrão, seu fileName deve conter / gs / bucket-name / duas vezes, estranho, mas funciona.

Usando esse blobKey, o URL de veiculação correto é criado

questionAnswers(1)

yourAnswerToTheQuestion