Ответ 1
exiftool делает работу для меня, она написана на perl, поэтому она должна работать для вас на любом o/s
http://www.sno.phy.queensu.ca/~phil/exiftool
использование:
exiftool -all= image.jpg
Я хочу удалить информацию из EXIF (включая эскизы, метаданные, информацию о камере... все!) из файлов JPEG, но я не хочу их повторно сжимать, поскольку повторное сжатие JPEG ухудшит качество, а также обычно увеличивая размер файла.
Я ищу решение для Unix/Linux, даже лучше, если вы используете командную строку. Если возможно, используйте ImageMagick (инструмент конвертации). Если это невозможно, небольшой Python, Perl, PHP (или другой общий язык в Linux) script будет в порядке.
Аналогичный вопрос существует, но связан с .NET.
exiftool делает работу для меня, она написана на perl, поэтому она должна работать для вас на любом o/s
http://www.sno.phy.queensu.ca/~phil/exiftool
использование:
exiftool -all= image.jpg
С imagemagick:
convert <input file> -strip <output file>
ImageMagick имеет параметр -strip, но он сжимает изображение перед сохранением. Таким образом, этот параметр бесполезен для моей необходимости.
В этом разделе форума ImageMagick объясняется, что в ImageMagick отсутствует поддержка операций без потерь в формате JPEG (когда это меняется, публикуйте комментарий со ссылкой!), И предлагается использовать jpegtran (из libjpeg):
jpegtran -copy none image.jpg > newimage.jpg
jpegtran -copy none -outfile newimage.jpg image.jpg
(Если вы не уверены, что я отвечу на свой вопрос, прочитайте это, это и это)
Вы также можете посмотреть Exiv2 - это очень быстро (С++ и без рекомпрессии), это командная строка, а также предоставляет библиотеку для EXIF-манипуляции, с которой вы можете связать. Я не знаю, сколько дистрибутивов Linux делает его доступным, но в CentOS, доступном в настоящее время в базовом репо.
Использование:
exiv2 rm image.jpg
Я бы предложил jhead
:
man jhead
jhead -purejpg image.jpg
Только 123Kb на Debian/Ubuntu, не сжимать повторно. Обратите внимание, что оно изменяет изображение, поэтому скопируйте оригинал, если вам это нужно.
Недавно я предпринял этот проект на C. Код ниже делает следующее:
1) Возвращает текущую ориентацию изображения.
2) Удаляет все данные, содержащиеся в APP1
(данные Exif) и APP2
(данные Flashpix), путем гашения.
3) Восстанавливает маркер ориентации APP1
и устанавливает его в исходное значение.
4) Находит первый маркер EOI
(Конец изображения) и обрезает файл, если nessasary.
Прежде всего следует отметить следующие:
1) Эта программа используется для моей камеры Nikon. Формат Nikon JPEG добавляет до самого конца каждого создаваемого файла. Они кодируют эти данные до конца файла изображения, создавая второй маркер 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;
}
Надеюсь, это поможет кому-то!
Подсказка для удобства: если вы работаете в 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"
Для EXIF-полосы без потерь вы можете использовать libexif, который доступен с cygwin. Удалите EXIF и миниатюру, чтобы анонимизировать изображение:
$ exif --remove --tag=0 --remove-thumbnail exif.jpg -o anonymized.jpg
Drag-n-drop .bat
файл для использования с cygwin:
@ECHO OFF
exif --remove --tag=0 --remove-thumbnail %~1
Другое программное обеспечение:
"MetabilityQuickFix удаляет всю вашу личную информацию и данные местоположения GPS со всех ваших фотографий одним щелчком мыши. Он с легкостью удаляет все элементы метаданных из блоков данных Exif, Iptc и XMP из ваших файлов JPEG и автоматически создает резервные копии исходные файлы"
"Инструмент для удаления/очистки/удаления необработанных метаданных (мусор) из файлов JPG/JPEG/JFIF и PNG. Качество изображения НЕ ЗНАЕТ. Включает поддержку командной строки. Просто укажите папку или файл в командной строке (подстановочные знаки допускается)"
Мы использовали это для удаления данных широты из файла TIFF:
exiv2 mo -M"del Exif.GPSInfo.GPSLatitude" IMG.TIF
где вы можете использовать exiv2 -pa IMG.TIF
для exiv2 -pa IMG.TIF
списка всех метаданных.