Làm cách nào để xóa dữ liệu EXIF ​​mà không cần giải nén JPEG?


127

Tôi muốn xóa thông tin EXIF ​​(bao gồm hình thu nhỏ, siêu dữ liệu, thông tin máy ảnh ... mọi thứ!) Khỏi các tệp JPEG, nhưng tôi không muốn giải nén nó, vì việc giải nén JPEG sẽ làm giảm chất lượng, cũng như thường làm tăng Kích thước tập tin.

Tôi đang tìm kiếm một giải pháp Unix / Linux, thậm chí tốt hơn nếu sử dụng dòng lệnh. Nếu có thể, sử dụng ImageMagick (công cụ chuyển đổi). Nếu điều đó là không thể, một tập lệnh Python nhỏ, Perl, PHP (hoặc ngôn ngữ phổ biến khác trên Linux) sẽ ổn.

Có một câu hỏi tương tự, nhưng liên quan đến .NET .


Câu trả lời:


166

exiftool thực hiện công việc cho tôi, nó được viết bằng perl vì vậy sẽ phù hợp với bạn trên bất kỳ o / s nào

https://exiftool.org/

sử dụng :

exiftool -all= image.jpg

6
Một số tùy chọn thú vị khác: "-o outfile.jpg" hoặc "-out outfile.jpg", "-overwrite_origen" hoặc "-overwrite_origen_in_place", "-P" hoặc "-preserve", "-r" hoặc "-recurse"
Denilson Sá Maia

6
Tôi chỉ đi qua chủ đề này để tìm kiếm điều tương tự. Tôi chỉ nghĩ rằng tôi sẽ thêm một nhận xét ở đây cho người dùng Ubuntu: Tập lệnh có sẵn trong repos Ubuntu dưới dạng libimage-exiftool-perl: sudo apt-get install libimage-exiftool-perl
user605331

7
Hoặc với homebrewbrew install exiftool
cwd 29/12/13

6
Nếu bạn thực sự tin tưởng chương trình thêm -overwrite_originalchuyển đổi và chương trình sẽ không tạo các tập tin sao lưu.
Salman A

10
Việc sử dụng được chấp nhận với tùy chọn -all = xóa TẤT CẢ các thẻ khỏi image.jpg của bạn! Câu trả lời đúng sẽ làexiftool -EXIF= image.jpg
PeterCo

85

Với hình ảnh:

convert <input file> -strip <output file>

21
Xin lỗi, nhưng -strip không hoạt động như mong đợi, vì ImageMagick vẫn giải nén tệp JPEG.
Denilson Sá Maia

5
Lưu ý, nhân tiện, "-strip" có thể hữu ích nếu ai đó đang thực hiện các biến đổi khác với tệp. Cũng lưu ý rằng "-thumbnail 123x456" tương đương với "-strip -resize 123x456".
Denilson Sá Maia

15
+1 vì việc này dễ dàng hơn nhiều so với việc tải xuống một công cụ mới.
Dave Dopson

13
Lưu ý -striploại bỏ các cấu hình màu. Đối với bất kỳ ai đang cố gắng tước dữ liệu EXIF ​​mà không mất thông tin hồ sơ, hãy xem giải pháp của tôi tại đây: stackoverflow.com/a/17516878/1854499
Robbert

2
OP nên cập nhật câu trả lời này, vì nó sai hai lần.
berbt 4/2/2015

49

ImageMagick có tham số -strip , nhưng nó nén lại hình ảnh trước khi lưu. Vì vậy, tham số này là vô ích cho nhu cầu của tôi.

Chủ đề này từ diễn đàn ImageMagick giải thích rằng không có hỗ trợ cho các hoạt động không mất dữ liệu JPEG trong ImageMagick (bất cứ khi nào thay đổi, vui lòng gửi bình luận với một liên kết!) Và đề xuất sử dụng jpegtran (từ libjpeg):

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

(Nếu bạn không chắc chắn về tôi trả lời câu hỏi của riêng tôi, đọc nàynàyđây )


1
Đã thử phương pháp jpegtran nhưng trong hầu hết các trường hợp, nó tăng kích thước tệp thay vì giảm. Trong hầu hết các trường hợp, bạn muốn làm điều này để giảm kích thước tập tin.
Codebeat

1
Khi thử sử dụng ImageMagick để loại bỏ dữ liệu exif, tôi nhận thấy rằng tôi đã kết thúc với một tệp lớn hơn so với những gì tôi bắt đầu. Điều này khiến tôi tin rằng Imagemagick đang mã hóa dữ liệu bạn muốn loại bỏ và đang lưu trữ nó ở một nơi khác trong tệp. Gọi tôi là lỗi thời, nhưng khi tôi xóa một cái gì đó khỏi một tập tin, tôi muốn một kích thước tập tin nhỏ hơn nếu không cùng kích thước. Bất kỳ kết quả khác đề nghị khai thác dữ liệu.
Deanie

1
Một điểm nhỏ: đối với tôi, không có lệnh nào trong số 2 lệnh được liệt kê hoạt động, thay vào đó là các công việc sau: jpegtran -copy none image.jpg newimage.jpg
ibic

@Codebeat Bạn cần thêm param -progressiveĐiều này sẽ giảm kích thước.
Tom

31

Bạn cũng có thể muốn xem xét Exiv2 - nó thực sự rất nhanh (C ++ không cần giải nén), đó là dòng lệnh và nó cũng cung cấp một thư viện để thao tác EXIF ​​mà bạn có thể liên kết. Tôi không biết có bao nhiêu bản phân phối Linux làm cho nó có sẵn, nhưng trong CentOS hiện tại nó có sẵn trong repo cơ sở.

Sử dụng:

exiv2 rm image.jpg

1
Cảm ơn người đàn ông, đây là người đầu tiên thực hiện công việc rất tốt mà không giảm chất lượng và nhanh chóng! Yo xứng đáng +100! Nhưng để loại bỏ TẤT CẢ các loại tiêu đề, tôi phải chỉ định tùy chọn -da nếu không nó sẽ không xóa thông tin adhop photoshop / creator khỏi jpg's. Dù sao tôi cũng đang dùng Windows.
Codebeat

Cảm ơn! Tôi muốn xác nhận rằng exiv2 sẽ hiển thị thông tin vị trí GPS để tôi có thể thấy rằng nó đã biến mất sau đó. Tùy chọn mặc định để in là "tóm tắt" không bao gồm thông tin GPS. Để xem tất cả thông tin bạn phải sử dụng: exiv2 -pa pr image.jpg
Rob Russell

Xin lưu ý rằng công cụ này đã phá hủy chất lượng của một số JPEG của tôi, may mắn là tôi đã có bản sao lưu
Steel Brain

@SteelBrain, điều đó thực sự kỳ lạ - bạn có thể chia sẻ một trong những hình ảnh JPEG bị ảnh hưởng bởi điều này không?
Bogdan Stăncescu

Đây là giải pháp an toàn nhất
Mohammed Shareef C

20

Tôi muốn đề xuất jhead:

man jhead
jhead -purejpg image.jpg

Chỉ 123Kb trên debian / ubfox, không nén lại. Lưu ý rằng mặc dù nó làm thay đổi hình ảnh, vì vậy hãy sao chép bản gốc nếu bạn cần.


2

Gần đây tôi đã thực hiện dự án này trong C. Đoạn mã dưới đây thực hiện như sau:

1) Lấy hướng hiện tại của hình ảnh.

2) Xóa tất cả dữ liệu có trong APP1(dữ liệu Exif) và APP2(dữ liệu Flashpix) bằng cách xóa.

3) Tái tạo APP1điểm đánh dấu định hướng và đặt nó về giá trị ban đầu.

4) Tìm EOIđiểm đánh dấu đầu tiên (Kết thúc hình ảnh) và cắt bớt tệp nếu không cần thiết.

Một số điều cần lưu ý đầu tiên là:

1) Chương trình này được sử dụng cho máy ảnh Nikon của tôi. Định dạng JPEG của Nikon thêm một số thứ vào cuối mỗi tệp mà nó tạo. Họ mã hóa dữ liệu này đến cuối tệp hình ảnh bằng cách tạo EOIđiểm đánh dấu thứ hai . Thông thường các chương trình hình ảnh đọc đến EOIđiểm đánh dấu đầu tiên được tìm thấy. Sau đó, Nikon có thông tin mà chương trình của tôi cắt ngắn.

2) Vì đây là định dạng của Nikon, nên nó giả định big endianthứ tự byte. Nếu tệp hình ảnh của bạn sử dụng little endian, một số điều chỉnh cần phải được thực hiện.

3) Khi cố gắng sử dụng ImageMagickđể tách dữ liệu exif, tôi nhận thấy rằng tôi đã kết thúc với một tệp lớn hơn so với những gì tôi bắt đầu. Điều này khiến tôi tin rằng Imagemagickđang mã hóa dữ liệu bạn muốn loại bỏ và đang lưu trữ nó ở một nơi khác trong tệp. Gọi tôi là lỗi thời, nhưng khi tôi xóa một cái gì đó khỏi một tập tin, tôi muốn một kích thước tập tin nhỏ hơn nếu không cùng kích thước. Bất kỳ kết quả khác đề nghị khai thác dữ liệu.

Và đây là mã:

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

Hy vọng điều này sẽ giúp được ai đó!


1

Gợi ý cho thuận tiện: Nếu bạn đang ở trên Windows, bạn có thể áp dụng tệp REG cho sổ đăng ký, để cài đặt một mục trong menu ngữ cảnh, do đó bạn có thể dễ dàng xóa siêu dữ liệu bằng cách nhấp chuột phải vào tệp và chọn lệnh.

Ví dụ: (nhớ chỉnh sửa các đường dẫn để trỏ đến nơi cài đặt các tệp thực thi trên máy tính của bạn):


Đối với các tệp JPEG, JPG, JPE, JFIF: lệnh " Xóa siêu dữ liệu "
(sử dụng ExifTool , giữ nguyên tệp gốc làm bản sao lưu)
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"

Đối với tệp PNG: lệnh " Chuyển đổi sang PNG đã rút gọn "
(sử dụng ImageMagick , thay đổi dữ liệu ghi đè tệp gốc)
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"

Liên quan: chuyển đổi PNG sang ICO trong menu ngữ cảnh .


1

Chúng tôi đã sử dụng điều này để xóa dữ liệu vĩ độ khỏi tệp TIFF:

exiv2 mo -M"del Exif.GPSInfo.GPSLatitude" IMG.TIF nơi bạn có thể sử dụng exiv2 -pa IMG.TIFđể liệt kê tất cả các siêu dữ liệu.


1

Đối với dải EXIF ​​lossless, bạn có thể sử dụng libexif , có sẵn với cygwin . Xóa cả EXIF ​​và hình thu nhỏ để ẩn danh một hình ảnh:

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

.batTập tin kéo thả để sử dụng với cygwin:

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

0

Phần mềm khác:

MetFility QuickFix

"MetabilityQuickFix loại bỏ tất cả thông tin cá nhân và dữ liệu vị trí GPS của bạn khỏi tất cả các ảnh của bạn, chỉ bằng một cú nhấp chuột. Nó sẽ xóa tất cả các mục siêu dữ liệu từ các khối dữ liệu Exif, Iptc và XMP khỏi các tệp JPEG của bạn và tự động tạo bản sao dự phòng của các tệp gốc "

Vũ nữ thoát y JPEG & PNG

"Một công cụ để tước / làm sạch / xóa siêu dữ liệu không liên tục (rác) khỏi các tệp JPG / JPEG / JFIF & PNG. Chất lượng hình ảnh KHÔNG ĐƯỢC HIỆU LỰC. Bao gồm hỗ trợ dòng lệnh. Chỉ cần chỉ định thư mục hoặc tệp trên dòng lệnh (cho phép ký tự đại diện)"


0

Nếu bạn đã sử dụng jpegoptim, bạn cũng có thể sử dụng nó để xóa exif.

jpegoptim -s *
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.