如何在不重新压缩JPEG的情况下删除EXIF数据?

问题描述 投票:99回答:10

我想从JPEG文件中删除EXIF信息(包括缩略图,元数据,相机信息......一切!),但我不想重新压缩它,因为重新压缩JPEG会降低质量,并且通常会增加文件大小。

我正在寻找一个Unix / Linux解决方案,如果使用命令行更好。如果可能,使用ImageMagick(转换工具)。如果那是不可能的,那么一个小的Python,Perl,PHP(或Linux上的其他通用语言)脚本就可以了。

有一个类似的问题,但related to .NET

unix imagemagick jpeg exif
10个回答
141
投票

exiftool为我工作,它是用perl编写的,所以应该在任何o / s上为你工作

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

用法:

exiftool -all= image.jpg

0
投票

对于无损EXIF条,你可以使用exiv2 -pa IMG.TIF,这是libexif。删除EXIF和缩略图以匿名化图像:

available with cygwin

用于cygwin的drag-n-drop $ exif --remove --tag=0 --remove-thumbnail exif.jpg -o anonymized.jpg 文件:

.bat

75
投票

使用imagemagick:

convert <input file> -strip <output file>

45
投票

ImageMagick具有-strip参数,但在保存之前会重新压缩图像。因此,这个参数对我的需求毫无用处。

This topic from ImageMagick forum解释说在ImageMagick中不支持JPEG无损操作(每当这个更改时,请发布带有链接的评论!),并建议使用jpegtran(来自libjpeg):

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

(如果你不确定我回答我自己的问题,请阅读thisthis以及this


26
投票

您可能还想查看Exiv2 - 它非常快(C ++并且没有重新压缩),它是命令行,它还提供了一个可以链接的EXIF操作库。我不知道有多少Linux发行版可供使用,但在CentOS中它目前在基础仓库中可用。

用法:

exiv2 rm image.jpg

20
投票

我建议jhead

man jhead
jhead -purejpg image.jpg

在debian / ubuntu上只有123Kb,不会重新压缩。请注意,它会改变图像,因此如果需要,请复制原始图像。


2
投票

我最近在C中进行了这个项目。下面的代码执行以下操作:

1)获取图像的当前方向。

2)通过消隐删除APP1(Exif数据)和APP2(Flashpix数据)中包含的所有数据。

3)重新创建APP1方向标记并将其设置为原始值。

4)找到第一个qazxsw poi标记(图像结束)并在必要时截断文件。

首先要注意的一些事项是:

1)此程序用于我的尼康相机。尼康的JPEG格式为它创建的每个文件的最末端添加了一些东西。他们通过创建第二个EOI标记将这些数据编码到图像文件的末尾。通常,图像程序读取到第一个EOI标记。尼康在此之后有我的程序截断的信息。

2)因为这是尼康格式,它假设EOI字节顺序。如果您的图像文件使用big endian,则需要进行一些调整。

3)当试图使用little endian去除exif数据时,我注意到我最终得到的文件比我开始时的文件大。这让我相信ImageMagick正在编码您想要剥离的数据,并将其存储在文件中的其他位置。叫我老式的,但是当我从文件中删除某些东西时,我想要一个文件大小,如果不是相同的大小。任何其他结果表明数据挖掘。

以下是代码:

Imagemagick

希望这有助于某人!


2
投票

为方便起见提示:如果您使用的是Windows,则可以将REG文件应用于注册表,以在上下文菜单中安装条目,这样您可以通过右键单击文件并选择命令来轻松删除元数据。

例如(记得编辑路径以指向计算机上可执行文件的安装位置):


对于JPEG,JPG,JPE,JFIF文件:命令“删除元数据” (使用#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; } ,保留原始文件作为备份) ExifTool

JPG,RemoveExif.reg

exiftool -all= image.jpg

对于PNG文件:命令“转换为缩小的PNG” (使用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" ,更改数据覆盖原始文件) ImageMagick

PNG-Minify.reg

convert -background none -strip -set filename:n "%t" image.png "%[filename:n].png"

相关: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"


0
投票

其他软件:

convert PNGs to ICO in context menu

“只需点击一下鼠标,MetabilityQuickFix即可从您的所有照片中删除所有个人信息和GPS位置数据。它可以安全地从您的JPEG文件中清除所有元数据项目,包括Exif,Iptc和XMP数据块,并自动生成原始文件的备份副本“

MetAbility QuickFix

“从JPG / JPEG / JFIF和PNG文件中剥离/清除/删除不必要的元数据(垃圾)的工具。图像质量不受影响。包括命令行支持。只需在命令行上指定文件夹或文件(允许使用通配符)”


0
投票

我们用它从TIFF文件中删除纬度数据:

JPEG & PNG Stripper,您可以使用exiv2 mo -M"del Exif.GPSInfo.GPSLatitude" IMG.TIF列出所有元数据。

© www.soinside.com 2019 - 2024. All rights reserved.