จะลบข้อมูล EXIF ​​โดยไม่บีบอัด JPEG ได้อย่างไร?


127

ฉันต้องการลบข้อมูล EXIF ​​(รวมถึงภาพขนาดย่อข้อมูลเมตาข้อมูลกล้อง ... ทุกอย่าง!) จากไฟล์ JPEG แต่ฉันไม่ต้องการบีบอัดข้อมูลใหม่เนื่องจากการบีบอัด JPEG ใหม่จะทำให้คุณภาพลดลงและโดยปกติจะเพิ่ม ขนาดไฟล์

ฉันกำลังมองหาโซลูชัน Unix / Linux ซึ่งจะดีกว่านี้หากใช้บรรทัดคำสั่ง ถ้าเป็นไปได้ให้ใช้ ImageMagick (เครื่องมือแปลง) หากเป็นไปไม่ได้สคริปต์ Python, Perl, PHP (หรือภาษาทั่วไปอื่น ๆ บน Linux) ก็ใช้ได้

มีคำถามที่คล้ายกัน แต่ที่เกี่ยวข้องกับ .NET


คำตอบ:


166

exiftool ทำงานให้ฉันมันเขียนด้วย perl ดังนั้นควรทำงานให้คุณใน o / s ใด ๆ

https://exiftool.org/

การใช้งาน:

exiftool -all= image.jpg

6
ตัวเลือกอื่น ๆ ที่น่าสนใจ: "-o outfile.jpg" หรือ "-out outfile.jpg", "-overwrite_original" หรือ "-overwrite_original_in_place", "-P" หรือ "-preserve", "-r" หรือ "-recurse"
Denilson Sá Maia

6
ฉันเพิ่งมาเจอกระทู้นี้กำลังมองหาสิ่งเดียวกัน ฉันแค่คิดว่าฉันจะเพิ่มความคิดเห็นที่นี่สำหรับผู้ใช้ Ubuntu: สคริปต์มีอยู่ใน repos ของ Ubuntu เช่น libimage-exiftool-perl: sudo apt-get install libimage-exiftool-perl
user605331

7
หรือกับ homebrewbrew install exiftool
cwd

6
หากคุณเชื่อถือสวิตช์เพิ่มโปรแกรมจริงๆ-overwrite_originalและโปรแกรมจะไม่สร้างไฟล์สำรอง
Salman A

10
การใช้งานที่ยอมรับด้วยตัวเลือก -all = ลบแท็กทั้งหมดออกจาก image.jpg ของคุณ! คำตอบที่ถูกต้องคือexiftool -EXIF= image.jpg
PeterCo

85

ด้วย imagemagick:

convert <input file> -strip <output file>

21
ขออภัย - -strip ไม่ทำงานตามที่คาดไว้เนื่องจาก ImageMagick ยังคงบีบอัดไฟล์ JPEG ซ้ำ
Denilson Sá Maia

5
โปรดทราบว่า "-strip" อาจมีประโยชน์หากมีคนทำการแปลงไฟล์อื่น ๆ โปรดทราบว่า "-thumbnail 123x456" เทียบเท่า ALMOST กับ "-strip -resize 123x456"
Denilson Sá Maia

15
+1 เพราะทำได้ง่ายกว่าการดาวน์โหลดเครื่องมือใหม่หลายไมล์
Dave Dopson

13
หมายเหตุ-stripลบโปรไฟล์สี สำหรับใครก็ตามที่พยายามดึงข้อมูล EXIF ​​โดยไม่สูญเสียข้อมูลโปรไฟล์ดูวิธีแก้ปัญหาของฉันที่นี่: stackoverflow.com/a/17516878/1854499
Robbert

2
OP ควรอัปเดตคำตอบนี้เนื่องจากผิดสองครั้ง
Berbt

49

ImageMagick มีพารามิเตอร์-stripแต่จะบีบอัดรูปภาพอีกครั้งก่อนบันทึก ดังนั้นพารามิเตอร์นี้จึงไร้ประโยชน์สำหรับความต้องการของฉัน

หัวข้อนี้จากฟอรัม ImageMagickอธิบายว่าไม่มีการรองรับการทำงานแบบไม่สูญเสีย JPEG ใน ImageMagick (เมื่อใดก็ตามที่มีการเปลี่ยนแปลงโปรดโพสต์ความคิดเห็นพร้อมลิงค์!) และแนะนำให้ใช้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 distros ให้ใช้งานได้กี่ตัว แต่ใน CentOS ตอนนี้มีให้ใช้งานใน base repo

การใช้งาน:

exiv2 rm image.jpg

1
ขอบคุณคนนี้เป็นคนแรกที่ทำงานได้ดีโดยไม่สูญเสียคุณภาพและเห็นได้ชัดอย่างรวดเร็ว! โย่สมควรได้รับ +100! แต่ในการลบส่วนหัวทุกประเภทฉันต้องระบุตัวเลือก -da มิฉะนั้นจะไม่ลบข้อมูล adobe photoshop / ผู้สร้างออกจาก jpg ฉันใช้ Windows อยู่แล้ว
Codebeat

ขอบคุณ! ฉันต้องการยืนยันว่า exiv2 จะแสดงข้อมูลตำแหน่ง GPS เพื่อที่ฉันจะได้เห็นว่ามันหายไปแล้ว ตัวเลือกเริ่มต้นสำหรับการพิมพ์คือ "สรุป" ซึ่งไม่รวมข้อมูล GPS หากต้องการดูข้อมูลทั้งหมดที่คุณต้องใช้: exiv2 -pa pr image.jpg
Rob Russell

โปรดทราบว่าเครื่องมือนี้ทำลายคุณภาพของ JPEG บางส่วนของฉันโชคดีที่ฉันมีข้อมูลสำรอง
Steel Brain

@SteelBrain มันแปลกมาก - คุณสามารถแบ่งปันภาพ JPEG ที่ได้รับผลกระทบจากสิ่งนี้ได้หรือไม่?
Bogdan Stăncescu

นี่คือทางออกที่ปลอดภัยที่สุด
Mohammed Shareef C

20

ฉันขอเสนอjhead:

man jhead
jhead -purejpg image.jpg

เฉพาะ 123Kb บน debian / ubuntu ไม่บีบอัดใหม่ โปรดทราบว่ารูปภาพจะกลายพันธุ์ดังนั้นให้คัดลอกต้นฉบับหากคุณต้องการ


2

ฉันเพิ่งทำโครงการนี้ใน C. โค้ดด้านล่างทำสิ่งต่อไปนี้:

1) รับการวางแนวปัจจุบันของภาพ

2) ลบข้อมูลทั้งหมดที่มีอยู่ในAPP1(ข้อมูล Exif) และAPP2(ข้อมูล Flashpix) โดยการเว้นว่าง

3) สร้างAPP1เครื่องหมายการวางแนวใหม่และตั้งค่าเป็นค่าเดิม

4) ค้นหาEOIเครื่องหมายแรก(End of Image) และตัดทอนไฟล์หากไม่มี

สิ่งที่ควรทราบก่อนอื่น ได้แก่ :

1) โปรแกรมนี้ใช้สำหรับกล้อง Nikon ของฉัน รูปแบบ JPEG ของ Nikon จะเพิ่มส่วนท้ายของแต่ละไฟล์ที่สร้างขึ้น พวกเขาเข้ารหัสข้อมูลนี้ที่ส่วนท้ายของไฟล์รูปภาพโดยการสร้างEOIเครื่องหมายที่สอง โดยปกติโปรแกรมรูปภาพจะอ่านEOIเครื่องหมายแรกที่พบ Nikon มีข้อมูลหลังจากนี้ซึ่งโปรแกรมของฉันตัดทอน

2) เนื่องจากเป็นรูปแบบ Nikon จึงถือว่า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: คำสั่ง " Convert to minified 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"

ที่เกี่ยวข้อง: แปลง PNGs ถึง ICO ในเมนูบริบท


1

เราใช้สิ่งนี้เพื่อลบข้อมูลละติจูดออกจากไฟล์ TIFF:

exiv2 mo -M"del Exif.GPSInfo.GPSLatitude" IMG.TIF ที่คุณสามารถใช้exiv2 -pa IMG.TIFเพื่อแสดงรายการข้อมูลเมตาทั้งหมด


1

สำหรับ lossless EXIF ตัดคุณสามารถใช้libexifซึ่งเป็นใช้ได้กับ Cygwin ลบทั้ง EXIF ​​และรูปขนาดย่อเพื่อไม่ระบุชื่อรูปภาพ:

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

ลาก n-drop .batไฟล์สำหรับใช้กับ cygwin:

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

0

ซอฟต์แวร์อื่น ๆ :

MetAbility QuickFix

"MetabilityQuickFix ดึงข้อมูลส่วนบุคคลและข้อมูลตำแหน่ง GPS ทั้งหมดของคุณออกจากภาพถ่ายทั้งหมดของคุณด้วยการคลิกเมาส์เพียงครั้งเดียวโดยจะขัดข้อมูลเมตาดาต้าทั้งหมดในรูปแบบ Exif, Iptc และ XMP จากไฟล์ JPEG ของคุณอย่างปลอดภัยและสร้างสำเนาสำรองของไฟล์ต้นฉบับโดยอัตโนมัติ "

JPEG & PNG Stripper

"เครื่องมือสำหรับการลอก / ทำความสะอาด / ลบข้อมูลเมตาที่ไม่จำเป็น (ขยะ) จากไฟล์ JPG / JPEG / JFIF และ PNG คุณภาพของภาพไม่มีผลรวมถึงการรองรับบรรทัดคำสั่งเพียงระบุโฟลเดอร์หรือไฟล์ในบรรทัดคำสั่ง (อนุญาตให้ใช้สัญลักษณ์แทน)"


0

หากคุณใช้ jpegoptim อยู่แล้วคุณสามารถใช้มันเพื่อลบ exif ได้เช่นกัน

jpegoptim -s *
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.