JPEG를 다시 압축하지 않고 EXIF ​​데이터를 제거하는 방법은 무엇입니까?


127

JPEG 파일에서 EXIF ​​정보 (썸네일, 메타 데이터, 카메라 정보 ... 모두 포함!)를 제거하고 싶지만 다시 압축하고 싶지 않습니다. 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
나는 방금 똑같은 것을 찾고있는이 스레드를 발견했습니다. 난 그냥 우분투 사용자를 위해 여기에 댓글을 추가 거라고 생각 : 스크립트는 libimage - exiftool - 펄과 우분투의 repos에서 사용할 수 있습니다 : sudo apt-get install libimage-exiftool-perl
— user605331

7
또는 homebrew와 함께brew install exiftool
— cwd dec

6
프로그램 추가 스위치 를 정말로 신뢰하면 프로그램 -overwrite_original이 백업 파일을 생성하지 않습니다.
— Salman A

10
-all = 옵션과 함께 허용 된 사용법은 image.jpg에서 모든 태그를 제거합니다! 정답은 것exiftool -EXIF= image.jpg
— PeterCo

85

imagemagick 사용 :

convert <input file> -strip <output file>

21
죄송합니다. ImageMagick이 여전히 JPEG 파일을 다시 압축하기 때문에 -strip이 예상대로 작동하지 않습니다.
— Denilson Sá Maia

5
참고로, 누군가 파일에 대해 다른 변환을 수행하는 경우 "-strip"이 유용 할 수 있습니다. 또한 "-thumbnail 123x456"은 "-strip -resize 123x456"과 거의 동일합니다.
— Denilson Sá Maia

15
새로운 도구를 다운로드하는 것보다 훨씬 쉬웠 기 때문입니다.
— Dave Dopson 2012

13
참고 -strip는 색상 프로파일을 제거합니다. 프로필 정보를 잃지 않고 EXIF 데이터를 제거하려고 누군가를 위해, 여기 내 솔루션을 참조하십시오 stackoverflow.com/a/17516878/1854499
— Robbert

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

(내 자신의 질문에 대한 대답이 확실하지 않은 경우 this and this and this )


1
jpegtran 방법을 시도했지만 대부분의 경우 파일 크기를 줄이는 대신 증가시킵니다. 대부분의 경우 파일 크기를 줄이기 위해이 작업을 수행합니다.
— Codebeat

1
ImageMagick을 사용하여 exif 데이터를 제거하려고 할 때 처음 시작한 것보다 더 큰 파일이 생성되었음을 알았습니다. 이로 인해 Imagemagick이 제거하려는 데이터를 인코딩하고 파일의 다른 곳에 저장하고 있다고 믿게됩니다. 구식이라고 부르지 만 파일에서 무언가를 제거 할 때 파일 크기가 같지 않으면 더 작아야합니다. 다른 모든 결과는 데이터 마이닝을 제안합니다.
— Deanie

1
사소한 점 : 나에게는 나열된 두 명령 중 어느 것도 작동하지 않고 대신 다음 작업이 작동했습니다. jpegtran -copy none image.jpg newimage.jpg
— ibic

@Codebeat 매개 변수를 추가해야합니다 -progressive. 이렇게하면 크기가 줄어 듭니다.
— Tom

31

Exiv2 를 살펴볼 수도 있습니다. 정말 빠르며 (C ++ 및 재 압축 없음) 명령 줄이며 연결할 수있는 EXIF ​​조작을위한 라이브러리도 제공합니다. 얼마나 많은 Linux 배포판을 사용할 수 있는지 모르겠지만 CentOS에서는 현재 기본 저장소에서 사용할 수 있습니다.

용법:

exiv2 rm image.jpg

1
고마워요, 이것은 품질 손실과 타오르는 빠른 속도로 일을 아주 잘하는 최초의 것입니다! Yo +100을받을 자격이 있습니다! 그러나 모든 유형의 헤더를 제거하려면 -da 옵션을 지정해야합니다. 그렇지 않으면 jpg에서 adobe photoshop / creator 정보를 제거하지 않습니다. 어쨌든 Windows를 사용하고 있습니다.
— Codebeat

감사! exiv2가 GPS 위치 정보를 표시하여 나중에 사라 졌음을 확인하고 싶었습니다. 인쇄를위한 기본 옵션은 GPS 정보를 제외한 "요약"입니다. 사용해야하는 모든 정보를 보려면 : exiv2 -pa pr image.jpg
— Rob Russell

이 도구는 일부 JPEG의 품질을 손상 시켰습니다. 다행히도 백업이있었습니다
— Steel Brain

@SteelBrain, 정말 이상합니다. 영향을받은 JPEG 이미지 중 하나를 공유 할 수 있습니까?
— Bogdan Stăncescu

이것은 가장 안전한 솔루션입니다
— 모하메드 샤리프 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)이 프로그램은 내 Nikon 카메라에 사용됩니다. Nikon의 JPEG 형식은 생성하는 각 파일의 맨 끝에 무언가를 추가합니다. 두 번째 EOI마커 를 만들어 이미지 파일의 끝에이 데이터를 인코딩합니다 . 일반적으로 이미지 프로그램은 처음까지 읽습니다.EOI 발견 된 마커 . Nikon에는 내 프로그램이 잘리는 정보가 있습니다.

2) Nikon 형식이므로 big endian바이트 순서를 가정합니다 . 이미지 파일이를 사용하는 little endian경우 일부 조정이 필요합니다.

3) ImageMagickexif 데이터를 제거 하는 데 사용하려고 할 때 처음 시작한 것보다 더 큰 파일이 생성되었음을 알았습니다. 이것은 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.TIFexiv2 -pa IMG.TIF모든 메타 데이터를 나열 하는 데 사용할 수 있습니다 .


1

대한 손실 EXIF 당신이 사용할 수있는 제거 libexif 이며, Cygwin에서 사용할 수를 . 이미지를 익명화하려면 EXIF와 축소판을 모두 제거하십시오.

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

.batcygwin에서 사용할 드래그 앤 드롭 파일 :

@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 *
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.