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


127

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

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

有一个类似的问题,但与.NET有关


Answers:


166

exiftool为我完成了工作,它是用perl编写的,因此在任何操作系统上都可以为您工作

https://exiftool.org/

用法:

exiftool -all= image.jpg

6
其他一些有趣的选项:“-o outfile.jpg”或“ -out outfile.jpg”,“-overwrite_original”或“ -overwrite_original_in_place”,“-P”或“ -preserve”,“-r”或“ -recurse”
DenilsonSáMaia

6
我只是碰到这个线程在寻找相同的东西。我只是想在这里为Ubuntu用户添加评论:该脚本在Ubuntu存储库中以libimage-exiftool-perl的形式提供: sudo apt-get install libimage-exiftool-perl
user605331

7
还是使用自制软件brew install exiftool
-cwd

6
如果您确实信任该程序,请添加-overwrite_original开关,并且该程序将不会创建备份文件。
Salman A

10
选项-all =可接受的用法将从您的image.jpg中删除所有标签!正确的答案是exiftool -EXIF= image.jpg
PeterCo '16

85

使用imagemagick:

convert <input file> -strip <output file>

21
抱歉,-strip无法正常工作,因为ImageMagick仍重新压缩JPEG文件。
DenilsonSáMaia

5
注意,顺便说一句,如果有人对该文件进行其他转换,则“ -strip”可能很有用。另请注意,“-thumbnail 123x456”在等效于“ -strip -resize 123x456”的情况下。
DenilsonSáMaia

15
+1,因为这比下载新工具要容易得多。
戴夫·多普森

13
注意-strip删除颜色配置文件。对于尝试剥离EXIF数据而不丢失配置文件信息的任何人,请参阅此处的解决方案:stackoverflow.com/a/17516878/1854499
罗伯特

2
OP应该更新此答案,因为它有两次错误。
berbt

49

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

来自ImageMagick论坛的本主题说明,ImageMagick不支持JPEG无损操作(每当更改时,请发表带有链接的评论!),并建议使用jpegtran(来自libjpeg):

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

(如果您不知道我的回答我的问题,阅读这个这个这个


1
尝试了jpegtran方法,但在大多数情况下,它增加了文件大小而不是减小了文件大小。在大多数情况下,您想这样做以减小文件大小。
Codebeat

1
当尝试使用ImageMagick剥离exif数据时,我注意到最终得到的文件比开始时要大。这使我相信Imagemagick正在编码要剥离的数据,并将其存储在文件中的其他位置。称我为老式,但是当我从文件中删除某些内容时,我希望文件的大小要小一些,即使大小不一样。其他任何结果都建议进行数据挖掘。
Deanie

1
一点要点:对我来说,列出的2个命令都没有起作用,而是以下命令起作用: jpegtran -copy none image.jpg newimage.jpg
ibic

@Codebeat您需要添加参数,-progressive这将减小大小。
汤姆

31

您可能还想研究一下Exiv2,它确实非常快(C ++ 无需重新压缩),它是命令行,并且它还提供了可链接的EXIF操作库。我不知道有多少Linux发行版可以使用它,但是在CentOS中它目前在基本存储库中可用。

用法:

exiv2 rm image.jpg

1
谢谢,这是第一个在不损失质量和快速燃烧的情况下很好地完成工作的人!de值得+100!但是要删除所有类型的标题,我必须指定-da选项,否则它不会从jpg的文件中删除Adobe Photoshop / Creator信息。我还是在Windows上。
Codebeat

谢谢!我想确认exiv2将显示GPS位置信息,以便可以看到它已经消失了。打印的默认选项是“摘要”,其中不包括GPS信息。要查看所有信息,您必须使用:exiv2 -pa pr image.jpg
Rob Russell

请注意,此工具破坏了我一些JPEG的质量,幸运的是我有一个备份
Steel Brain 2016年

@SteelBrain,真的很奇怪–您可以共享受此影响的JPEG图像之一吗?
BogdanStăncescu16年

这是最安全的解决方案
Mohammed Shareef C

20

我建议jhead

man jhead
jhead -purejpg image.jpg

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


2

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

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

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

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

4)查找第一个EOI标记(图像结尾),并在必要时将其截断。

首先要注意的是:

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

2)因为这是尼康格式,所以采用big endian字节顺序。如果您的图片文件使用little endian,则需要进行一些调整。

3)当尝试ImageMagick剥离exif数据时,我发现最终得到的文件比开始时要大。这使我相信Imagemagick正在编码要剥离的数据,并将其存储在文件中的其他位置。称我为老式,但是当我从文件中删除某些内容时,我希望文件的大小要小一些,即使大小不一样。其他任何结果都建议进行数据挖掘。

这是代码:

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

希望这对某人有帮助!


1

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

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


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

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

相关:在上下文菜单中将PNG转换为ICO



1

对于无损EXIF剥去你可以使用libexif,这是可用的cygwin。同时删除EXIF和缩略图以匿名化图像:

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

.bat用于cygwin 的拖放文件:

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

0

其他软件:

MetAbility QuickFix

“ MetabilityQuickFix只需单击一下鼠标,即可从所有照片中剥离所有个人信息和GPS位置数据。它可以安全地从JPEG文件中清除Exif,Iptc和XMP数据块中的所有元数据项,并自动制作原始文件的备份副本”

JPEG和PNG剥离器

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


0

如果您已经使用jpegoptim,则也可以使用它来删除exif。

jpegoptim -s *
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.