¿Cómo eliminar datos EXIF ​​sin volver a comprimir el JPEG?

127

Quiero eliminar la información EXIF ​​(incluida la miniatura, los metadatos, la información de la cámara ... ¡todo!) De los archivos JPEG, pero no quiero volver a comprimirla, ya que volver a comprimir el JPEG degradará la calidad y, por lo general, aumentará tamaño del archivo.

Estoy buscando una solución Unix / Linux, incluso mejor si uso la línea de comandos. Si es posible, use ImageMagick (herramienta de conversión). Si eso no es posible, un pequeño script Python, Perl, PHP (u otro lenguaje común en Linux) estaría bien.

Hay una pregunta similar, pero relacionada con .NET .

Denilson Sá Maia
fuente
1
relacionado: askubuntu.com/questions/260810/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

166

Exiftool hace el trabajo por mí, está escrito en perl, así que debería funcionar para usted en cualquier o / s

https://exiftool.org/

uso:

exiftool -all= image.jpg
Chris
fuente
66
Algunas otras opciones interesantes: "-o outfile.jpg" o "-out outfile.jpg", "-overwrite_original" o "-overwrite_original_in_place", "-P" o "-preserve", "-r" o "-recurse"
Denilson Sá Maia
66
Acabo de encontrar este hilo buscando lo mismo. Solo pensé en agregar un comentario aquí para los usuarios de Ubuntu: el script está disponible en los repositorios de Ubuntu como libimage-exiftool-perl: sudo apt-get install libimage-exiftool-perl
user605331
77
O con homebrewbrew install exiftool
cwd
66
Si realmente confía en el programa, agregue el -overwrite_originalinterruptor y el programa no creará los archivos de respaldo.
Salman A
10
¡El uso aceptado con la opción -all = elimina TODAS las etiquetas de su imagen.jpg! La respuesta correcta seríaexiftool -EXIF= image.jpg
PeterCo
85

Con imagemagick:

convert <input file> -strip <output file>
JayM
fuente
21
Lo sentimos, pero -strip no funciona como se esperaba, ya que ImageMagick todavía vuelve a comprimir el archivo JPEG.
Denilson Sá Maia
55
Tenga en cuenta, por cierto, que "-strip" podría ser útil si alguien está haciendo otras transformaciones con el archivo. También tenga en cuenta que "-thumbnail 123x456" es casi equivalente a "-strip -resize 123x456".
Denilson Sá Maia
15
+1 porque esto fue mucho más fácil que descargar una nueva herramienta.
Dave Dopson
13
Nota -stripelimina los perfiles de color. Para cualquiera que intente eliminar datos EXIF ​​sin perder información de perfil, vea mi solución aquí: stackoverflow.com/a/17516878/1854499
Robbert
2
OP debería actualizar esta respuesta, ya que es dos veces incorrecta.
berbt
49

ImageMagick tiene el parámetro -strip , pero vuelve a comprimir la imagen antes de guardarla. Por lo tanto, este parámetro es inútil para mi necesidad.

Este tema del foro ImageMagick explica que no hay soporte para operaciones JPEG sin pérdida en ImageMagick (cada vez que esto cambie, ¡publique un comentario con un enlace!), Y sugiere usar jpegtran (de libjpeg):

jpegtran -copy none -progressive image.jpg > newimage.jpg
jpegtran -copy none -progressive -outfile newimage.jpg image.jpg

(Si no está seguro de que responda mi propia pregunta, lea esto y esto y esto )

Denilson Sá Maia
fuente
1
Probé el método jpegtran pero en la mayoría de los casos aumenta el tamaño del archivo en lugar de disminuirlo. En la mayoría de los casos, desea hacer esto para disminuir el tamaño del archivo.
Codebeat
1
Al intentar usar ImageMagick para eliminar datos exif, noté que terminé con un archivo más grande de lo que comencé. Esto me lleva a creer que Imagemagick está codificando los datos que desea eliminar, y los está almacenando en otro lugar del archivo. Llámame anticuado, pero cuando elimino algo de un archivo, quiero que el tamaño del archivo sea más pequeño, si no del mismo tamaño. Cualquier otro resultado sugiere minería de datos.
Deanie
1
Un punto menor: para mí, ninguno de los 2 comandos enumerados funcionó, en cambio, los siguientes trabajos: jpegtran -copy none image.jpg newimage.jpg
ibic
@Codebeat Necesita agregar param -progressiveEsto reducirá el tamaño.
Tom
31

También es posible que desee examinar Exiv2 : es realmente rápido (C ++ y sin recompresión), es la línea de comandos y también proporciona una biblioteca para la manipulación EXIF ​​con la que puede vincular. No sé cuántas distribuciones de Linux lo hacen disponible, pero en CentOS actualmente está disponible en el repositorio base.

Uso:

exiv2 rm image.jpg
Bogdan Stăncescu
fuente
1
¡Gracias hombre, este es el primero que hace el trabajo muy bien sin pérdida de calidad y muy rápido! ¡Te mereces un +100! Pero para eliminar TODO tipo de encabezados, tengo que especificar la opción -da; de lo contrario, no eliminará la información de Adobe Photoshop / Creator de los archivos jpg. Estoy en Windows de todos modos.
Codebeat
¡Gracias! Quería confirmar que exiv2 mostraría la información de ubicación del GPS para poder ver que desapareció después. La opción predeterminada para imprimir es "resumen", que excluye la información del GPS. Para ver toda la información que tiene que usar: exiv2 -pa pr image.jpg
Rob Russell
Tenga en cuenta que esta herramienta destruyó la calidad de algunos de mis archivos JPEG, por suerte tuve una copia de seguridad
Steel Brain
@SteelBrain, eso es realmente extraño: ¿puedes compartir una de las imágenes JPEG afectadas por esto?
Bogdan Stăncescu
Esta es la solución más segura
Mohammed Shareef C
20

Yo propondría jhead:

man jhead
jhead -purejpg image.jpg

Solo 123Kb en debian / ubuntu, no se vuelve a comprimir. Sin embargo, tenga en cuenta que muta la imagen, así que copie el original si lo necesita.

VasiliNovikov
fuente
2

Recientemente emprendí este proyecto en C. El siguiente código hace lo siguiente:

1) Obtiene la orientación actual de la imagen.

2) Elimina todos los datos contenidos en APP1(Datos Exif) y APP2(Datos Flashpix) en blanco.

3) Recrea el APP1marcador de orientación y lo establece en el valor original.

4) Encuentra el primer EOImarcador (Fin de imagen) y trunca el archivo si es necesario.

Algunas cosas a tener en cuenta primero son:

1) Este programa se usa para mi cámara Nikon. El formato JPEG de Nikon agrega algo al final de cada archivo que crea. Codifican estos datos al final del archivo de imagen creando un segundo EOImarcador. Normalmente, los programas de imagen leen hasta el primer EOImarcador encontrado. Nikon tiene información después de esto que mi programa trunca.

2) Debido a que esto es para el formato Nikon, asume el big endianorden de los bytes. Si usa su archivo de imagen little endian, es necesario hacer algunos ajustes.

3) Al intentar usar ImageMagickpara eliminar datos exif, noté que terminé con un archivo más grande de lo que comencé. Esto me lleva a creer que Imagemagickestá codificando los datos que desea eliminar, y los está almacenando en otro lugar del archivo. Llámame anticuado, pero cuando elimino algo de un archivo, quiero que el tamaño del archivo sea más pequeño, si no del mismo tamaño. Cualquier otro resultado sugiere minería de datos.

Y aquí está el código:

#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <string.h>
#include <errno.h>

// Declare constants.
#define COMMAND_SIZE     500
#define RETURN_SUCCESS     1
#define RETURN_FAILURE     0
#define WORD_SIZE         15

int check_file_jpg (void);
int check_file_path (char *file);
int get_marker (void);
char * ltoa (long num);
void process_image (char *file);

// Declare global variables.
FILE *fp;
int orientation;
char *program_name;

int main (int argc, char *argv[])
{
// Set program name for error reporting.
    program_name = basename(argv[0]);

// Check for at least one argument.
    if(argc < 2)
    {
        fprintf(stderr, "usage: %s IMAGE_FILE...\n", program_name);
        exit(EXIT_FAILURE);
    }

// Process all arguments.
    for(int x = 1; x < argc; x++)
        process_image(argv[x]);

    exit(EXIT_SUCCESS);
}

void process_image (char *file)
{
    char command[COMMAND_SIZE + 1];

// Check that file exists.
    if(check_file_path(file) == RETURN_FAILURE)
        return;

// Check that file is an actual JPEG file.
    if(check_file_jpg() == RETURN_FAILURE)
    {
        fclose(fp);
        return;
    }

// Jump to orientation marker and store value.
    fseek(fp, 55, SEEK_SET);
    orientation = fgetc(fp);

// Recreate the APP1 marker with just the orientation tag listed.
    fseek(fp, 21, SEEK_SET);
    fputc(1, fp);

    fputc(1, fp);
    fputc(18, fp);
    fputc(0, fp);
    fputc(3, fp);
    fputc(0, fp);
    fputc(0, fp);
    fputc(0, fp);
    fputc(1, fp);
    fputc(0, fp);
    fputc(orientation, fp);

// Blank the rest of the APP1 marker with '\0'.
    for(int x = 0; x < 65506; x++)
        fputc(0, fp);

// Blank the second APP1 marker with '\0'.
    fseek(fp, 4, SEEK_CUR);

    for(int x = 0; x < 2044; x++)
        fputc(0, fp);

// Blank the APP2 marker with '\0'.
    fseek(fp, 4, SEEK_CUR);

    for(int x = 0; x < 4092; x++)
        fputc(0, fp);

// Jump the the SOS marker.
    fseek(fp, 72255, SEEK_SET);

    while(1)
    {
// Truncate the file once the first EOI marker is found.
        if(fgetc(fp) == 255 && fgetc(fp) == 217)
        {
            strcpy(command, "truncate -s ");
            strcat(command, ltoa(ftell(fp)));
            strcat(command, " ");
            strcat(command, file);
            fclose(fp);
            system(command);
            break;
        }
    }
}

int get_marker (void)
{
    int c;

// Check to make sure marker starts with 0xFF.
    if((c = fgetc(fp)) != 0xFF)
    {
        fprintf(stderr, "%s: get_marker: invalid marker start (should be FF, is %2X)\n", program_name, c);
        return(RETURN_FAILURE);
    }

// Return the next character.
    return(fgetc(fp));
}

int check_file_jpg (void)
{
// Check if marker is 0xD8.
    if(get_marker() != 0xD8)
    {
        fprintf(stderr, "%s: check_file_jpg: not a valid jpeg image\n", program_name);
        return(RETURN_FAILURE);
    }

    return(RETURN_SUCCESS);
}

int check_file_path (char *file)
{
// Open file.
    if((fp = fopen(file, "rb+")) == NULL)
    {
        fprintf(stderr, "%s: check_file_path: fopen failed (%s) (%s)\n", program_name, strerror(errno), file);
        return(RETURN_FAILURE);
    }

    return(RETURN_SUCCESS);
}

char * ltoa (long num)
{
// Declare variables.
        int ret;
        int x = 1;
        int y = 0;
        static char temp[WORD_SIZE + 1];
        static char word[WORD_SIZE + 1];

// Stop buffer overflow.
        temp[0] = '\0';

// Keep processing until value is zero.
        while(num > 0)
        {
                ret = num % 10;
                temp[x++] = 48 + ret;
                num /= 10;
        }

// Reverse the word.
        while(y < x)
        {
                word[y] = temp[x - y - 1];
                y++;
        }

        return word;
}

¡Espero que esto ayude a alguien!

Deanie
fuente
1

Sugerencia para mayor comodidad: si está en Windows, puede aplicar un archivo REG al registro para instalar una entrada en el menú contextual, de modo que pueda eliminar fácilmente los metadatos haciendo clic derecho en el archivo y seleccionando el comando.

Por ejemplo (recuerde editar las rutas para señalar dónde están instalados los ejecutables en su computadora):


Para archivos JPEG, JPG, JPE, JFIF: comando " Eliminar metadatos "
(usando ExifTool , conserva el archivo original como copia de seguridad)
exiftool -all= image.jpg

JPG-RemoveExif.reg

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\jpegfile\shell\RemoveMetadata]
@="Remove metadata"
[HKEY_CURRENT_USER\Software\Classes\jpegfile\shell\RemoveMetadata\command]
@="\"C:\\Path to\\exiftool.exe\" -all= \"%1\""
[HKEY_CURRENT_USER\Software\Classes\jpegfile\shell\RemoveMetadata]
"Icon"="C:\\Path to\\exiftool.exe,0"

Para archivos PNG: comando " Convertir a PNG minificado "
(usando ImageMagick , cambia los datos sobrescribiendo el archivo original)
convert -background none -strip -set filename:n "%t" image.png "%[filename:n].png"

PNG-Minify.reg

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\pngfile\shell\ConvertToMinifiedPNG]
@="Convert to minified PNG"
[HKEY_CURRENT_USER\Software\Classes\pngfile\shell\ConvertToMinifiedPNG\command]
@="\"C:\\Path to\\convert.exe\" -background none -strip -set filename:n \"%%t\" \"%1\" \"%%[filename:n].png\""
[HKEY_CURRENT_USER\Software\Classes\pngfile\shell\ConvertToMinifiedPNG]
"Icon"="C:\\Path to\\convert.exe,0"

Relacionado: convertir PNG a ICO en el menú contextual .

geekley
fuente
1

Utilizamos esto para eliminar los datos de latitud del archivo TIFF:

exiv2 mo -M"del Exif.GPSInfo.GPSLatitude" IMG.TIF donde puede usar exiv2 -pa IMG.TIFpara enumerar todos los metadatos.

Muhammet Ali Asan
fuente
1

Para la tira EXIF ​​sin pérdidas, puede usar libexif , que está disponible con cygwin . Elimine EXIF ​​y la miniatura para anonimizar una imagen:

$ exif --remove --tag=0 --remove-thumbnail exif.jpg -o anonymized.jpg

Arrastrar y soltar .batarchivo para usar con cygwin:

@ECHO OFF
exif --remove --tag=0 --remove-thumbnail %~1
radioxoma
fuente
0

Otro software:

MetAbility QuickFix

"MetabilityQuickFix elimina toda su información personal y datos de ubicación GPS de todas sus fotos, con un solo clic del mouse. Elimina todos los elementos de metadatos de los bloques de datos Exif, Iptc y XMP de forma segura de sus archivos JPEG y automáticamente realiza copias de seguridad de los archivos originales "

JPEG y PNG Stripper

"Una herramienta para eliminar / limpiar / eliminar metadatos innecesarios (basura) de archivos JPG / JPEG / JFIF y PNG. La calidad de la imagen NO ESTÁ AFECTADA. Incluye soporte de línea de comando. Solo especifique una carpeta o archivo en la línea de comando (se permiten comodines)"

Remus Rigo
fuente
0

Si ya usa jpegoptim, también puede usarlo para eliminar el exif.

jpegoptim -s *
Strifel
fuente