ฉันเพิ่งทำโครงการนี้ใน C. โค้ดด้านล่างทำสิ่งต่อไปนี้:
1) รับการวางแนวปัจจุบันของภาพ
2) ลบข้อมูลทั้งหมดที่มีอยู่ในAPP1
(ข้อมูล Exif) และAPP2
(ข้อมูล Flashpix) โดยการเว้นว่าง
3) สร้างAPP1
เครื่องหมายการวางแนวใหม่และตั้งค่าเป็นค่าเดิม
4) ค้นหาEOI
เครื่องหมายแรก(End of Image) และตัดทอนไฟล์หากไม่มี
สิ่งที่ควรทราบก่อนอื่น ได้แก่ :
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;
}
หวังว่านี่จะช่วยใครสักคน!