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 APP1
penanda orientasi dan menetapkannya ke nilai asli.
4) Menemukan EOI
penanda 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 EOI
penanda 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 endian
urutan byte. Jika file gambar Anda digunakan little endian
, beberapa penyesuaian perlu dilakukan.
3) Ketika mencoba menggunakan ImageMagick
untuk menghapus data exif, saya perhatikan bahwa saya berakhir dengan file yang lebih besar dari yang saya mulai. Ini membuat saya percaya bahwa Imagemagick
meng-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!