Як видалити EXIF-дані без повторного стискання JPEG?


127

Я хочу видалити EXIF ​​інформацію (включаючи мініатюру, метадані, інформацію про камеру ... все!) З файлів JPEG, але я не хочу її повторно створювати, оскільки повторне стиснення JPEG погіршить якість, а також зазвичай підвищить розмір файлу.

Я шукаю рішення Unix / Linux, ще краще, якщо використовувати командний рядок. Якщо можливо, використовуючи ImageMagick (інструмент перетворення). Якщо це неможливо, невеликий скрипт Python, Perl, PHP (або іншої загальної мови в Linux) буде нормальним.

Існує аналогічне запитання, але пов'язане з .NET .


Відповіді:


166

exiftool робить роботу для мене, вона написана в perl, тому вона повинна працювати для вас на будь-якому о

https://exiftool.org/

використання:

exiftool -all= image.jpg

6
Деякі інші цікаві параметри: "-o outfile.jpg" або "-out outfile.jpg", "-overwrite_original" або "-overwrite_original_in_place", "-P" або "-резервувати", "-r" або "-recurse"
Denilson Sá Maia

6
Я щойно натрапив на цю нитку, шукаючи те саме. Я просто подумав, що тут додам коментар для користувачів Ubuntu: Сценарій доступний у sudo apt-get install libimage-exiftool-perl
репортах

7
Або з домашньою мовоюbrew install exiftool
cwd

6
Якщо ви дійсно довіряєте програмі -overwrite_originalперемикач на додавання, і програма не створить резервні файли.
Салман

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
Зауважте, до речі, що "-стрип" може бути корисним, якщо хтось робить інші перетворення з файлом. Також зауважте, що "-символ 123x456" ALMOST еквівалентний "-strip -розмір 123x456".
Denilson Sá Maia

15
+1, тому що це було миль простіше, ніж завантаження нового інструменту.
Дейв Допсон

13
Примітка -stripвидаляє кольорові профілі. Для всіх, хто намагається зняти дані EXIF, не втрачаючи інформацію про профіль, дивіться моє рішення тут: stackoverflow.com/a/17516878/1854499
Роберт

2
ОП має оновити цю відповідь, оскільки це двічі неправильно.
берб

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 кодує дані, які ви хочете позбавити, і зберігає їх десь у файлі. Називайте мене старомодно, але коли я щось видалюю з файлу, я хочу, щоб розмір файлу був меншим, якщо не однакового розміру. Будь-які інші результати свідчать про пошук даних.
Діані

1
Незначний пункт: для мене жодна з двох перерахованих команд не працювала, замість цього працювали такі: jpegtran -copy none image.jpg newimage.jpg
ibic

@Codebeat Вам потрібно додати парам. -progressiveЦе зменшить розмір.
Том

31

Ви також можете заглянути в Exiv2 - це дійсно швидко (C ++ і відсутність рекомпресії), це командний рядок, а також надає бібліотеку для EXIF-маніпуляцій, з якими ви можете зв’язатись. Я не знаю, скільки дистрибутивів Linux робить його доступним, але в CentOS це доступно в базовій репо.

Використання:

exiv2 rm image.jpg

1
Спасибі людина, це перший, хто дуже добре виконує цю роботу без втрати якості та швидко палаючих! Йо заслуговує на +100! Але для видалення ВСІХ типів заголовків я повинен вказати параметр -da, інакше це не видалить Adobe Photoshop / info про творця з jpg. Я все одно в Windows.
Codebeat

Дякую! Я хотів підтвердити, що exiv2 показуватиме інформацію про місцезнаходження GPS, щоб я міг бачити, що його після не було. Параметр для друку за замовчуванням - "підсумок", який виключає інформацію про GPS. Щоб побачити всю інформацію, яку ви повинні використовувати: exiv2 -pa pr image.jpg
Роб Рассел

Зверніть увагу, що цей інструмент зруйнував якість деяких моїх JPEG, на щастя, у мене була резервна копія
Steel Brain

@SteelBrain, це дійсно дивно - чи можете ви поділитися одним із зображень, що впливають на це JPEG?
Богдан Станческу

Це найбезпечніше рішення
Мохаммед Шаріф C

20

Я б запропонував jhead:

man jhead
jhead -purejpg image.jpg

Тільки 123Kb на debian / ubuntu, не повторно стискається. Зауважте, що воно мутує зображення, тому скопіюйте оригінал, якщо вам це потрібно.


2

Нещодавно я розпочав цей проект у C. Код нижче:

1) Отримує поточну орієнтацію зображення.

2) Видаляє всі дані, що містяться в даних APP1(Exif data) та APP2(Flashpix data), шляхом блокування.

3) Відтворює APP1маркер орієнтації та встановлює початкове значення.

4) Знаходить перший EOIмаркер (Кінець зображення) і обрізає файл, якщо це необхідно.

Деякі речі, які слід відзначити спочатку:

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: команда " Перетворити в мінімізований 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

Ми використовували це для видалення даних широти з файлу TIFF:

exiv2 mo -M"del Exif.GPSInfo.GPSLatitude" IMG.TIF де ви можете використати exiv2 -pa IMG.TIFсписок усіх метаданих.


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 з усіх ваших фотографій лише одним клацанням миші. Він очищає всі елементи метаданих у форматі Exif, Iptc та XMP-блоки даних безпечно з ваших файлів JPEG та автоматично робить резервні копії оригінальних файлів. "

Знімач JPEG та PNG

"Інструмент для зняття / очищення / видалення нецензурних метаданих (непотрібних) з файлів JPG / JPEG / JFIF та PNG. Якість зображення НЕ ВПЛИВЛЕНО. Включає підтримку командного рядка. Просто вкажіть папку або файл в командному рядку (дозволені маски)"


0

Якщо ви вже використовуєте jpegoptim, ви можете також використовувати його для видалення exif.

jpegoptim -s *
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.