nella mia app backend Engine Ho un metodo che ottiene un'immagine da Google Cloud Storage
Invia i dati delle immagini per android app da App Engine
@ApiMethod(
name = "getProfileImage",
path = "image",
httpMethod = ApiMethod.HttpMethod.GET)
public Image getProfileImage(@Named("imageName")String imageName){
try{
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = GoogleCredential.getApplicationDefault();
Storage.Builder storageBuilder = new Storage.Builder(httpTransport,new JacksonFactory(),credential);
Storage storage = storageBuilder.build();
Storage.Objects.Get getObject = storage.objects().get("mybucket", imageName);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// If you're not in AppEngine, download the whole thing in one request, if possible.
getObject.getMediaHttpDownloader().setDirectDownloadEnabled(false);
getObject.executeMediaAndDownloadTo(out);
byte[] oldImageData = out.toByteArray();
out.close();
ImagesService imagesService = ImagesServiceFactory.getImagesService();
return ImagesServiceFactory.makeImage(oldImageData);
}catch(Exception e){
logger.info("Error getting image named "+imageName);
}
return null;
}
il problema che sto avendo è come faccio ad ottenere i dati dell'immagine quando chiamo quello nella mia app per Android?
Poiché non è possibile restituire le primitive dal motore di app, l'ho convertito in un Image
in modo da poter chiamare getImageData()
nella mia app per ottenere il byte [].
Tuttavia, l'oggetto Immagine restituito all'app non è uguale a quello nel motore di app, quindi non esiste getImageData().
Come posso ottenere i dati delle immagini sulla mia app Android?
Se creo un oggetto contenente una variabile byte [], quindi imposto la variabile byte [] con i dati stringa e restituisco quell'oggetto dal metodo funzionerà?
Aggiornamento
L'immagine viene inviato dal app Android. (Questo codice può o non può essere corretto, non ho ancora il debug esso)
@WorkerThread
public String startResumableSession(){
try{
File file = new File(mFilePath);
long fileSize = file.length();
file = null;
String sUrl = "https://www.googleapis.com/upload/storage/v1/b/lsimages/o?uploadType=resumable&name="+mImgName;
URL url = new URL(sUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestProperty("Authorization","");
urlConnection.setRequestProperty("X-Upload-Content-Type","image/png");
urlConnection.setRequestProperty("X-Upload-Content-Length",String.valueOf(fileSize));
urlConnection.setRequestMethod("POST");
if(urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
return urlConnection.getHeaderField("Location");
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
private long sendNextChunk(String sUrl,File file,long skip){
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 524287;
long totalBytesSent = 0;
try{
long fileSize = file.length();
FileInputStream fileInputStream = new FileInputStream(file);
skip = fileInputStream.skip(skip);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
totalBytesSent = skip + bufferSize;
buffer = new byte[bufferSize];
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
try {
while (bytesRead > 0) {
try {
URL url = new URL(sUrl);
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
urlConnection.setChunkedStreamingMode(524287);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Content-Type","image/png");
urlConnection.setRequestProperty("Content-Length",String.valueOf(bytesRead));
urlConnection.setRequestProperty("Content-Range", "bytes "+String.valueOf(skip)+"-"+String.valueOf(totalBytesSent)+"/"+String.valueOf(fileSize));
DataOutputStream outputStream = new DataOutputStream(urlConnection.getOutputStream());
outputStream.write(buffer, 0, bufferSize);
int code = urlConnection.getResponseCode();
if(code == 308){
String range = urlConnection.getHeaderField("Range");
return Integer.parseInt(range.split("-")[1]);
}else if(code == HttpURLConnection.HTTP_CREATED){
return -1;
}
outputStream.flush();
outputStream.close();
outputStream = null;
} catch (OutOfMemoryError e) {
e.printStackTrace();
// response = "outofmemoryerror";
// return response;
return -1;
}
fileInputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
// response = "error";
// return response;
return -1;
}
}catch(Exception e){
e.printStackTrace();
}
return -1;
}
Edit 2:
A quanto pare la sua non è chiaro alla gente che sto usando endpoint nella mia app Android
io di solito uso Python in modo da non so lo si fa in Java, ma si può solo restituire l'URL immagine del profilo generato da Google Cloud Storage invece di restituire la matrice di byte. In questo modo, è possibile memorizzare nella cache l'URL del profilo per evitare di ricostruirlo tutto il tempo. –
Come @ Maël ha detto che non è necessario trasferire l'intera immagine attraverso il proprio stack (per motivi di prestazioni ma anche per ridurre i costi).Crei il tipo di immagine? Se sì, puoi postare la sua fonte? –
@ BenoîtSauvère le immagini provengono dall'app per android, ho aggiornato la domanda con quel codice. Per ottenere l'URL dell'immagine non devo scaricare comunque i dati dell'immagine? Quindi essenzialmente scaricherò i dati dell'immagine due volte, una volta sul server solo per ottenere l'Url di servizio e di nuovo sull'app client. Non sarebbe più inefficiente (costo) che ottenere i dati delle immagini dal server? Una volta che l'app per Android ottiene i dati dell'immagine il mio piano era di memorizzare l'immagine localmente in cache (salvarla su disco) in modo che non debba andare a prenderla nuovamente – tyczj