Bagaimana cara menghapus data EXIF ​​tanpa mengkompres ulang JPEG?

127

Saya ingin menghapus informasi EXIF ​​(termasuk thumbnail, metadata, info kamera ... semuanya!) Dari file JPEG, tetapi saya tidak ingin mengompresnya kembali, karena mengkompres ulang JPEG akan menurunkan kualitas, dan biasanya meningkatkan ukuran file.

Saya mencari solusi Unix / Linux, bahkan lebih baik lagi jika menggunakan command-line. Jika memungkinkan, gunakan ImageMagick (alat konversi). Jika itu tidak memungkinkan, skrip Python, Perl, PHP (atau bahasa umum lainnya pada Linux) kecil tidak masalah.

Ada pertanyaan serupa, tetapi terkait dengan .NET .

Denilson Sa Maia
sumber
1
terkait: askubuntu.com/questions/260810/…
Ciro Santilli 郝海东 冠状 病 六四 六四 事件

Jawaban:

166

exiftool melakukan pekerjaan untuk saya, ini ditulis dalam perl jadi harus bekerja untuk Anda pada setiap o / s

https://exiftool.org/

penggunaan:

exiftool -all= image.jpg
chris
sumber
6
Beberapa opsi menarik lainnya: "-o outfile.jpg" atau "-out outfile.jpg", "-overwrite_original" atau "-overwrite_original_in_place", "-P" atau "-preserve", "-r" atau "-recurse"
Denilson Sá Maia
6
Saya baru saja menemukan utas ini mencari hal yang sama. Saya hanya berpikir saya akan menambahkan komentar di sini untuk pengguna Ubuntu: Skrip tersedia di repo Ubuntu sebagai libimage-exiftool-perl: sudo apt-get install libimage-exiftool-perl
user605331
7
Atau dengan homebrewbrew install exiftool
cwd
6
Jika Anda benar-benar mempercayai program, tambahkan -overwrite_originalsakelar dan program tidak akan membuat file cadangan.
Salman A
10
Penggunaan yang diterima dengan opsi -all = menghapus SEMUA tag dari image.jpg Anda! Jawaban yang benar adalahexiftool -EXIF= image.jpg
PeterCo
85

Dengan imagemagick:

convert <input file> -strip <output file>
JayM
sumber
21
Maaf, tetapi -strip tidak berfungsi seperti yang diharapkan, karena ImageMagick masih mengkompres ulang file JPEG.
Denilson Sá Maia
5
Perhatikan, omong-omong, "-strip" itu mungkin berguna jika seseorang melakukan transformasi lain dengan file tersebut. Perhatikan juga bahwa "-thumbnail 123x456" adalah HAMPIR yang setara dengan "-strip -resize 123x456".
Denilson Sá Maia
15
Memberi +1 karena ini lebih mudah daripada mengunduh alat baru.
Dave Dopson
13
Catatan -stripmenghapus profil warna. Bagi siapa pun yang mencoba menghapus data EXIF ​​tanpa kehilangan informasi profil, lihat solusi saya di sini: stackoverflow.com/a/17516878/1854499
Robbert
2
OP harus memperbarui jawaban ini, karena itu dua kali salah.
berbt
49

ImageMagick memiliki parameter -strip , tetapi mengkompres ulang gambar sebelum disimpan. Jadi, parameter ini tidak berguna untuk kebutuhan saya.

Topik ini dari forum ImageMagick menjelaskan bahwa tidak ada dukungan untuk operasi lossless JPEG di ImageMagick (setiap kali ini berubah, silakan kirim komentar dengan tautan!), Dan sarankan menggunakan jpegtran (dari libjpeg):

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

(Jika Anda tidak yakin tentang saya menjawab pertanyaan saya sendiri, baca ini dan ini dan ini )

Denilson Sa Maia
sumber
1
Mencoba metode jpegtran tetapi dalam kebanyakan kasus ini meningkatkan filesize bukannya menguranginya. Dalam kebanyakan kasus, Anda ingin melakukan ini untuk mengurangi ukuran file.
Codebeat
1
Ketika mencoba menggunakan ImageMagick untuk menghapus data exif, saya perhatikan bahwa saya memiliki file yang lebih besar daripada yang saya mulai. Ini membuat saya percaya bahwa Imagemagick sedang menyandikan data yang ingin Anda hapus, dan menyimpannya di tempat lain di dalam file. Sebut saya kuno, tetapi ketika saya menghapus sesuatu dari file, saya ingin ukuran file lebih kecil jika tidak dengan ukuran yang sama. Hasil lainnya menyarankan penambangan data.
Deanie
1
Poin minor: bagi saya, tidak satupun dari 2 perintah yang terdaftar yang berfungsi, sebagai gantinya berfungsi sebagai berikut: jpegtran -copy none image.jpg newimage.jpg
ibic
@ Codebeat Anda perlu menambahkan param -progressiveIni akan mengurangi ukuran.
Tom
31

Anda mungkin juga ingin melihat ke Exiv2 - sangat cepat (C ++ dan tanpa kompresi ulang), itu baris perintah, dan juga menyediakan pustaka untuk manipulasi EXIF ​​yang dapat Anda tautkan. Saya tidak tahu berapa banyak distro Linux yang membuatnya tersedia, tetapi di CentOS saat ini tersedia di repo basis.

Pemakaian:

exiv2 rm image.jpg
Bogdan Stăncescu
sumber
1
Terima kasih kawan, ini yang pertama melakukan pekerjaan dengan sangat baik tanpa kehilangan kualitas dan sangat cepat! Anda berhak mendapatkan +100! Tetapi untuk menghapus SEMUA jenis header saya harus menentukan opsi -da jika tidak maka tidak akan menghapus adobe photoshop / info pembuat dari jpg's. Saya tetap di Windows.
Codebeat
Terima kasih! Saya ingin mengonfirmasi bahwa exiv2 akan menampilkan info lokasi GPS sehingga saya dapat melihat bahwa itu hilang. Pilihan standar untuk mencetak adalah "ringkasan" yang tidak termasuk info GPS. Untuk melihat semua info, Anda harus menggunakan: exiv2 -pa pr image.jpg
Rob Russell
Harap perhatikan bahwa alat ini menghancurkan kualitas beberapa JPEG saya, untungnya saya punya cadangan
Steel Brain
@SteelBrain, itu benar-benar aneh - dapatkah Anda membagikan salah satu gambar JPEG yang terpengaruh oleh ini?
Bogdan Stăncescu
Ini adalah solusi teraman
Mohammed Shareef C
20

Saya akan mengusulkan jhead:

man jhead
jhead -purejpg image.jpg

Hanya 123Kb pada debian / ubuntu, tidak kompres ulang. Catat bahwa itu mengubah gambar, jadi salin yang asli jika Anda membutuhkannya.

VasiliNovikov
sumber
2

Saya baru-baru ini melakukan proyek ini dalam C. Kode di bawah ini melakukan hal berikut:

1) Mendapat orientasi gambar saat ini.

2) Menghapus semua data yang terkandung dalam APP1(Exif data) dan APP2(Flashpix data) dengan mengosongkan.

3) Menciptakan APP1penanda orientasi dan menetapkannya ke nilai asli.

4) Menemukan EOIpenanda pertama (Akhir Gambar) dan memotong file jika perlu.

Beberapa hal yang perlu diperhatikan pertama adalah:

1) Program ini digunakan untuk kamera Nikon saya. Format JPEG Nikon menambahkan sesuatu ke akhir setiap file yang dibuatnya. Mereka menyandikan data ini ke akhir file gambar dengan membuat EOIpenanda kedua . Biasanya program gambar membaca hingga yang pertamaEOI penanda ditemukan. Nikon memiliki informasi setelah ini yang terpotong oleh program saya.

2) Karena ini untuk format Nikon, diasumsikan big endianurutan byte. Jika file gambar Anda digunakan little endian, beberapa penyesuaian perlu dilakukan.

3) Ketika mencoba menggunakan ImageMagickuntuk menghapus data exif, saya perhatikan bahwa saya berakhir dengan file yang lebih besar dari yang saya mulai. Ini membuat saya percaya bahwa Imagemagickmeng-encode data yang Anda inginkan dihapus, dan menyimpannya di tempat lain dalam file. Sebut saya kuno, tetapi ketika saya menghapus sesuatu dari file, saya ingin ukuran file lebih kecil jika tidak dengan ukuran yang sama. Hasil lainnya menyarankan penambangan data.

Dan ini kodenya:

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

Semoga ini bisa membantu seseorang!

Deanie
sumber
1

Petunjuk untuk kenyamanan: Jika Anda menggunakan Windows, Anda dapat menerapkan file REG ke registri, untuk menginstal entri dalam menu konteks, sehingga Anda dapat dengan mudah menghapus metadata dengan mengklik kanan file dan memilih perintah.

Misalnya (ingat untuk mengedit jalur untuk menunjuk ke tempat executable diinstal pada komputer Anda):


Untuk file JPEG, JPG, JPE, JFIF: perintah " Hapus metadata "
(menggunakan ExifTool , simpan file asli sebagai cadangan)
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"

Untuk file PNG: perintah " Konversi ke PNG yang diperkecil "
(menggunakan ImageMagick , ubah data yang menimpa file asli)
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"

Terkait: konversi PNG ke ICO dalam menu konteks .

geekley
sumber
1

Kami menggunakan ini untuk menghapus data lintang dari file TIFF:

exiv2 mo -M"del Exif.GPSInfo.GPSLatitude" IMG.TIF tempat Anda dapat menggunakannya exiv2 -pa IMG.TIFuntuk mendaftar semua metadata.

Muhammet Ali Asan
sumber
1

Untuk strip EXIF ​​lossless Anda dapat menggunakan libexif , yang tersedia dengan cygwin . Hapus EXIF ​​dan gambar mini untuk menganonimkan gambar:

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

Drag-n-drop .batfile untuk digunakan dengan cygwin:

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

Perangkat Lunak Lainnya:

QuickFix MetAbility

"MetabilityQuickFix menghapus semua informasi pribadi Anda dan data lokasi GPS dari semua foto Anda, hanya dengan satu klik mouse. Ini menggosok semua item metadata dari Exif, Iptc dan XMP, memblokir data dengan aman dari file JPEG Anda dan secara otomatis membuat salinan cadangan dari file asli "

JPEG & PNG Stripper

"Alat untuk melucuti / membersihkan / menghapus metadata yang tidak diperlukan (sampah) dari file JPG / JPEG / JFIF & PNG. Kualitas gambar TIDAK MEMPENGARUHI. Termasuk dukungan baris perintah. Cukup tentukan folder atau file pada commandline (wildcard diizinkan)"

Remus Rigo
sumber
0

Jika Anda sudah menggunakan jpegoptim, Anda dapat menggunakannya untuk menghapus exif juga.

jpegoptim -s *
perselisihan
sumber