How to delete EXIF ​​data without recompressing JPEG?

I want to delete information from EXIF ​​(including thumbnails, metadata, camera information ... everything!) From JPEG files, but I do not want to recompress them, because recompressing JPEG will degrade quality and also usually increase the file size.

I am looking for a solution for Unix / Linux, even better if you use the command line. If possible, use ImageMagick (conversion tool). If this is not possible, a small Python, Perl, PHP (or other common language on Linux) script will be fine.

A similar question exists, but is related to .NET .

+108
unix imagemagick jpeg exif
Apr 16 2018-10-16T00:
source share
10 answers

exiftool does the job for me, it is written in perl, so it should work for you on any o / s

http://www.sno.phy.queensu.ca/~phil/exiftool

using:

exiftool -all= image.jpg 
+146
Apr 16 2018-10-16T00:
source share

With imagemagick:

 convert <input file> -strip <output file> 
+78
Apr 16 2018-10-16T00:
source share

ImageMagick has the -strip option , but it compresses the image before saving. So this option is useless for my need.

This section of the ImageMagick forum explains that ImageMagick does not support lossless JPEG operations (when this changes, post a comment with a link!), And suggest using jpegtran (from libjpeg):

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

(If you are not sure that I will answer my question, read this, this and this )

+46
Apr 16 2018-10-16T00:
source share

You can also look at Exiv2 - it is very fast (C ++ and without recompression), it is a command line, and it also provides a library for EXIF ​​manipulation with which you can link. I don't know how many Linux distributions make it available, but on CentOS, currently available in the base repo.

Using:

 exiv2 rm image.jpg 
+28
Feb 28
source share

I would suggest jhead :

 man jhead jhead -purejpg image.jpg 

Only 123Kb on Debian / Ubuntu, do not compress again. Please note that it changes the image, so copy the original if you need it.

+20
Jul 30 '13 at 21:05
source share

I recently embarked on this C project. The code below does the following:

1) Returns the current image orientation.

2) Deletes all data contained in APP1 (Exif data) and APP2 (Flashpix data) by blanking.

3) Restores the orientation marker APP1 and sets it to its original value.

4) Find the first EOI marker (Image End) and crop the file if nessasary.

First of all, the following should be noted:

1) This program is used for my Nikon camera. The Nikon JPEG format adds to the very end of each file you create. They encode this data to the end of the image file, creating a second EOI token. Typically, image programs are read before the first EOI marker. After that, Nikon has information that my program truncates.

2) Since this is a Nikon format, it accepts a big endian byte order. If your image file uses little endian , some changes need to be made.

3) When I tried to use ImageMagick to delete exif data, I noticed that I got a larger file than I started. This makes me think that ImageMagick encodes the data you want to delete and stores it somewhere else in the file. Call me old-fashioned, but when I delete something from the file, I want the file size to be smaller, if not the same size. Any other results require data mining.

And here is the code:

 #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; } 

Hope this helps someone!

+2
Oct 27 '16 at 10:23
source share

Hint for convenience: if you are running Windows, you can apply the REG file to the registry to set the entry in the context menu so that you can easily delete the metadata by right-clicking on the file and choosing a command.

For example (do not forget to edit the paths to indicate where the executable files are installed on your computer):




For JPEG, JPG, JPE, JFIF files: Delete Metadata command
(using ExifTool , saves the original file as a backup)
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" 



For PNG files: Convert to Reduced PNG command
(using ImageMagick , modifies data by overwriting the original file)
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" 



Related: convert PNG to ICO in the context menu .

+1
Apr 03 '19 at 1:35
source share

For lossless EXIF ​​bands, you can use libexif , which is available with cygwin . Remove EXIF ​​and thumbnail to anonymize the image:

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

Drag-n-drop .bat file for use with cygwin:

 @ECHO OFF exif --remove --tag=0 --remove-thumbnail %~1 
+1
May 17 '19 at 16:43
source share

Other software:

MetAbility QuickFix

"MetabilityQuickFix removes all your personal information and GPS location data from all your photos with one click. It easily removes all metadata elements from Exif, Iptc and XMP data blocks from your JPEG files and automatically backs up the source files."

JPEG and PNG Stripper

"A tool to remove / clean / delete raw metadata (junk) from JPG / JPEG / JFIF and PNG files. Image quality DOES NOT KNOW. Includes command line support. Just specify a folder or file on the command line (wildcards are allowed)"

0
Apr 18 '16 at 2:55
source share

We used this to remove latitude data from a TIFF file:

exiv2 mo -M"del Exif.GPSInfo.GPSLatitude" IMG.TIF where you can use exiv2 -pa IMG.TIF to exiv2 -pa IMG.TIF list all metadata.

0
Apr 29 '19 at 19:07
source share



All Articles