2011-01-26 5 views
17

In Android, quando decodifica una bitmap da una foto sul telefono, i dati EXIF ​​nell'originale vengono persi. Sto inviando questa Bitmap al mio server tramite un socket e vorrei ricollegare i dati EXIF ​​mancanti ai dati inviati.Come collegare i metadati EXIF ​​a una bitmap serializzata in Android?

ho qualche codice che carica un oggetto Bitmap dal MediaStore e lo comprime ad un array di byte in preparazione per inviarlo su un socket:

Bitmap bitmap = ... 
ByteArrayOutputStream stream = new ByteArrayOutputStream(bitmap); 
bitmap.compress(CompressFormat.JPEG, 70, stream); 
byte[] input = stream.toByteArray(); 

voglio usare l'ExifInterface per arrivare alla EXIF i metadati nel jpeg originale sulla scheda SD e in qualche modo li aggiungo all'array di byte in uscita in modo che sarei in grado di estrarre un jpeg con tutti gli EXIF ​​corretti sul lato server (si spera senza farlo sul server). Finora, sono riuscito a usare l'ExifInterface di leggere tutti i dati EXIF:

String path = ... //bitmap file path 
ExifInterface exif = new ExifInterface(path); 
... = exif.getAttribute(...) 

EDIT: In modo ottimale, mi piacerebbe trovare una soluzione che non utilizza le librerie. Se potessi ottenere gli indici dell'array di byte del jpeg originale che contengono EXIF ​​e anteporre questi byte all'array di byte prodotto da bitmap.compress(...), sarebbe meglio.

+0

Forse ad avere successo con l'aggiunta di informazioni EXIF ​​per array di byte? – Vikas

risposta

7

Grazie a @Nick Campion e Sanselan.

codice di lavoro:

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
bitmap.compress(CompressFormat.JPEG, 100, bos); //Bitmap object is your image 
byte[] data = bos.toByteArray(); 

TiffOutputSet outputSet = null; 

IImageMetadata metadata = Sanselan.getMetadata(new File(filepath)); // filepath is the path to your image file stored in SD card (which contains exif info) 
JpegImageMetadata jpegMetadata = (JpegImageMetadata) metadata; 
if (null != jpegMetadata) 
{ 
    TiffImageMetadata exif = jpegMetadata.getExif(); 
    if (null != exif) 
    { 
     outputSet = exif.getOutputSet(); 
    } 
} 
if (null != outputSet) 
{ 
    bos.flush(); 
    bos.close(); 
    bos = new ByteArrayOutputStream(); 
    ExifRewriter ER = new ExifRewriter(); 
    ER.updateExifMetadataLossless(data, bos, outputSet); 
    data = bos.toByteArray(); //Update you Byte array, Now it contains exif information! 
} 
+0

Il codice sopra spesso non funziona come previsto con Sanselan Android. In particolare, se ridimensioni l'immagine, il codice sopra non copierà solo i metadati EXIF ​​ma sovrascriverà anche i dati dell'immagine, annullando il ridimensionamento. Sembra essere un problema Sanselano che altri hanno incontrato: http://mail-archives.apache.org/mod_mbox/commons-user/201103.mbox/%[email protected]%3E. Ho scritto una soluzione per questo problema qui: http://bricolsoftconsulting.com/2012/12/08/copying-exif-metadata-using-sanselan/ – Theo

+0

Funziona bene con me. ma 'Sanselan' dovrebbe puntare a https://commons.apache.org/proper/commons-imaging/ e' Sanselan.getMetadata' diventa 'Imaging.getMetadata' – Leon