ver una programa para online metadatos imagen fotos exiftool eliminar unix imagemagick jpeg exif

unix - una - ¿Cómo eliminar datos EXIF sin recomprimir el JPEG?



programa para eliminar metadatos (7)

Quiero eliminar la información EXIF ​​(incluidas las miniaturas, los metadatos, la información de la cámara ... ¡todo!) De los archivos JPEG, pero no quiero volver a comprimirla, ya que recomprimir el JPEG degradará la calidad y 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, una secuencia de comandos pequeña de Python, Perl, PHP (u otro lenguaje común en Linux) estaría bien.

Hay una pregunta similar, pero relacionada con .NET .


Con imagemagick:

convert <input file> -strip <output file>


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

Uso:

exiv2 rm image.jpg


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

Este tema del foro de ImageMagick explica que no hay soporte para operaciones JPEG sin pérdidas en ImageMagick (siempre que esto cambie, por favor publique un comentario con un enlace), y sugiere usar jpegtran (desde libjpeg):

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

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


Otro software:

MetAbility QuickFix

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

JPEG y PNG Stripper

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


Recientemente realicé 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) mediante el borrado.

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

4) Encuentra el primer marcador EOI (Fin de la imagen) y trunca el archivo si es nessasary.

Algunas cosas que debe notar 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 esta información hasta el final del archivo de imagen creando un segundo marcador EOI . Normalmente, los programas de imágenes se leen hasta el primer marcador EOI encontrado. Nikon tiene información después de esto que mi programa trunca.

2) Debido a que esto es para el formato de Nikon, supone un orden de bytes de big endian . Si su archivo de imagen usa little endian , se deben hacer algunos ajustes.

3) Cuando traté de usar ImageMagick para quitar datos exif, noté que terminé con un archivo más grande que el que comencé. Esto me lleva a creer que Imagemagick está codificando los datos que quiere eliminar, y los está almacenando en otro lugar del archivo. Llámame anticuado, pero cuando elimino algo de un archivo, quiero que un tamaño de archivo sea más pequeño si no es del mismo tamaño. Cualquier otro resultado sugiere la extracción 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!


Yo propondría jhead :

man jhead jhead -purejpg image.jpg

  • el paquete en Debian (/ ubuntu) tiene solo 123 Kb de tamaño
  • no pierde calidad porque no se vuelve a comprimir
  • el programa muta la imagen, por lo que es mejor hacer una copia de seguridad si quieres