Imagen de Android cambiar el tamaño y la preservación de los datos EXIF (orientación, rotación, etc.)

Si tu Android app utiliza la cámara del dispositivo para tomar una imagen y, a continuación, cambia el tamaño de ella (esto es muy, muy común para reducir el tamaño para subir), usted no puede darse cuenta de que esta operación de cambio de tamaño tiras los metadatos Exif.

Esto puede causar problemas, especialmente si el dispositivo en cuestión se basa en la «Orientación» de la etiqueta para mostrar correctamente la imagen en posición vertical.

Los diferentes dispositivos Android de la manija de la cámara/imagen de la rotación de diferentes maneras – mi fiel antiguo Nexus One parece que siempre girar la imagen inmediatamente después de la captura, de modo que el archivo nativo de contenidos siempre son «honrados» cuando se ve.

Sin embargo, otros dispositivos (especialmente los teléfonos Samsung en mis pruebas), hacer no rotar el contenido del archivo de imagen – más bien, establecer el Exif de la ‘Orientación’ de la etiqueta. Cuando la imagen se muestra más adelante, el código de la imagen debe detectar la presencia de la Orientación de la ‘etiqueta’ y rotar la imagen de forma adecuada. Pero si usted ha hecho cualquier mapa de bits de procesamiento de la imagen y la guarda en un archivo nuevo, todos los datos Exif se pierde.

Además de los datos de Orientación, usted también podría perder otros metadatos valiosos, tales como marca, modelo, etc.

Esto me confundió por un par de semanas (la imagen aparece en vertical cuando se muestra en el teléfono de la galería, pero luego llega a mi servidor con mala orientación y sin aparente de metadatos). Voy a echar esto de la auto-pregunta aquí para ayudar a otros. Este blog fue muy útil:

Android re-tamaño de la imagen sin perder la información EXIF

InformationsquelleAutor Mike Repass | 2012-11-28

4 Kommentare

  1. 19

    Como otros han indicado, debe copiar los datos Exif de la imagen original a la final de la imagen redimensionada. El Sanselan Android biblioteca es generalmente el mejor para esto. Dependiendo de la versión del sistema operativo Android, el ExifInterface a veces daña el Exifdata.

    Además, el ExifInterface también se ocupa de un número limitado de etiquetas Exif — es decir, sólo las etiquetas que se «conoce». Sanselan en el otro lado va a mantener todos los Exiftags y marcador de notas.

    Aquí es un blog que muestra cómo utilizar Sanselan para copiar los datos de la imagen:

    Copia de los metadatos Exif utilizando Sanselan

    Por CIERTO, en Android yo también tienden a rotar las imágenes y eliminar la Orientación Exiftag. Por ejemplo, en un Nexus S con Android 4.03, la cámara fue la creación de una orientación de la etiqueta en el Exifmetadata, pero el webview estaba ignorando que la información y la visualización de la imagen de forma incorrecta. Lamentablemente, la rotación de la imagen real de los datos y extracción de la Exiforientation etiqueta es la única manera de conseguir que cada programa para mostrar las imágenes correctamente.

    • Gracias Theo, agradezco esta respuesta y la han aceptado. ¿Tienes un enlace para obtener más información sobre este «Dependiendo de la versión del sistema operativo Android, el ExifInterface a veces corrompe los datos EXIF.»
    • Es basado en mi experiencia, y no soy la primera persona en encontrar que ExifInterface está libre de errores [1]. Dependiendo de cuánto tiempo tengo para los próximos días, podría reunir una serie de casos ilustrativos y el informe de nuevo. [1] mail-archives.apache.org/mod_mbox/commons-issues/201106.mbox/…
    • he probado el código, y parece copiar la mayoría de los/todos los atributos de algunos de los dispositivos y las imágenes. ejemplos de atributos que no copia bien : ISOSpeedRatings, FocalLength, FNumber . ¿Puede por favor explicar cómo podría ser? Lo he probado en un nexus 4 dispositivo con Android 4.4.2 , y en comparación con el ExifInterface creado en el archivo original y el archivo de nuevo.
  2. 45

    Tan lejos como puedo decir, no es no mecanismo para conservar los metadatos de forma automática o incluso instantánea de lo que está allí y transferencia en masa.

    Más bien, parece que usted debe comprobar explícitamente por las propiedades específicas de las y los copia a sí mismo para el nuevo archivo de imagen usando el ExifInterface.

    http://developer.android.com/reference/android/media/ExifInterface.html

    Algo así como:

    ExifInterface oldExif = new ExifInterface(oldImagePath);
    String exifOrientation = oldExif.getAttribute(ExifInterface.TAG_ORIENTATION);
    
    if (exifOrientation != null) {
       ExifInterface newExif = new ExifInterface(imagePath);
       newExif.setAttribute(ExifInterface.TAG_ORIENTATION, exifOrientation);
       newExif.saveAttributes();
    }
    • Esto funcionó a la perfección. Gracias!
  3. 33

    Para los perezosos, aquí una función reutilizable:

    public static void copyExif(String oldPath, String newPath) throws IOException
    {
        ExifInterface oldExif = new ExifInterface(oldPath);
    
        String[] attributes = new String[]
        {
                ExifInterface.TAG_APERTURE,
                ExifInterface.TAG_DATETIME,
                ExifInterface.TAG_DATETIME_DIGITIZED,
                ExifInterface.TAG_EXPOSURE_TIME,
                ExifInterface.TAG_FLASH,
                ExifInterface.TAG_FOCAL_LENGTH,
                ExifInterface.TAG_GPS_ALTITUDE,
                ExifInterface.TAG_GPS_ALTITUDE_REF,
                ExifInterface.TAG_GPS_DATESTAMP,
                ExifInterface.TAG_GPS_LATITUDE,
                ExifInterface.TAG_GPS_LATITUDE_REF,
                ExifInterface.TAG_GPS_LONGITUDE,
                ExifInterface.TAG_GPS_LONGITUDE_REF,
                ExifInterface.TAG_GPS_PROCESSING_METHOD,
                ExifInterface.TAG_GPS_TIMESTAMP,
                ExifInterface.TAG_IMAGE_LENGTH,
                ExifInterface.TAG_IMAGE_WIDTH,
                ExifInterface.TAG_ISO,
                ExifInterface.TAG_MAKE,
                ExifInterface.TAG_MODEL,
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.TAG_SUBSEC_TIME,
                ExifInterface.TAG_SUBSEC_TIME_DIG,
                ExifInterface.TAG_SUBSEC_TIME_ORIG,
                ExifInterface.TAG_WHITE_BALANCE
        };
    
        ExifInterface newExif = new ExifInterface(newPath);
        for (int i = 0; i < attributes.length; i++)
        {
            String value = oldExif.getAttribute(attributes[i]);
            if (value != null)
                newExif.setAttribute(attributes[i], value);
        }
        newExif.saveAttributes();
    }
    • Si cambia el tamaño, recuerde actualizar o no copia TAG_IMAGE_LENGTH y TAG_IMAGE_WIDTH
  4. 0

    Ya 2019 y todavía no existe una mejor respuesta de los propuestos por @prom85, Mike Repass y Theo.

    En 2016, Android equipo presentó ExifInterface De La Biblioteca De Soporte lo que puede ser la mejor opción si quieres tener consisent comportamiento entre versiones de Android. Terminé la creación de un subconjunto de etiquetas ExifInterface#EXIF_TAGS (código fuente) y acabo de iterar sobre este subconjunto para extraer los metadatos de los archivos de entrada y la pusieron en una salida. Si usted alguna vez un requisito para copiar todas las etiquetas que te recomiendo que no lo haga! El valor de algunas de las etiquetas debe ser actualizado en consecuencia de todos modos (por ejemplo, TAG_IMAGE_LENGTH y TAG_IMAGE_WIDTH). Personalmente, yo seguía haciendo preguntas ¿por qué tenemos que mantener a todos los metedata de datos en primer lugar, se diferencia lo que se obtiene entre los dispositivos y la cámara que se use de todos modos) y nos dimos cuenta de que la ubicación de gps y datos de fecha/hora es así necesitas.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea