从C中的文件中提取jpeg文件

我试图从内存卡文件中提取jpeg文件。 程序将一次读取512字节块,如果块以JPEG识别字节开头,我的程序应该将这些字节写入输出文件。 它应该继续写入这些字节,直到它找到另一个JPEG识别字节序列,此时它应该停止写入.jpg文件并写入新文件。 每个文件应命名为00x.jpg,其中x是#。

我的程序编译但不生成所有jpeg。 应该有16个JPEG,但它只产生7个。

int main(void) { // open file for reading FILE* file = fopen("card.raw", "r"); // Open the file for reading // target file FILE* image; // buffer of bytes uint8_t buffer[512]; // check for NULL file if (file == NULL) { fclose(file); printf("Could not open file"); return 1; } // Prefixes of a jpeg file uint8_t jpeg1[4] = {0xff, 0xd8, 0xff, 0xe0}; uint8_t jpeg2[4] = {0xff, 0xd8, 0xff, 0xe1}; // keep track of jpegs opened int pic = 0; int match = 0; // is file open? int open = 0; // stores first 4 bytes of block uint8_t check[4]; int byteNum; byteNum = fread(buffer, 512, 1, file); // while there are bytes to be read in the file while(fread(buffer,512, 1, file) > 0) { for (int x=0; x < 4; x++) { check[x] = buffer[x]; } // compares first 4 bytes of buffer segment to jpeg prefixes to determine match if((memcmp(check, jpeg1,4) == 0) || (memcmp(check, jpeg2, 4) == 0)) { match = 1; } // if encounter a jpeg and file is open, close the file and set match to false if (match == 1 && open == 1) { fclose(image); open = 0; match = 0; } // if match is true and file is closed, create jpeg output file, increment pic#, set file to open, set match to false, open target file if (match == 1 && open == 0) { // stores name of jpegfile char jpegName[8]; // stores the jpeg file name with the # jpeg sprintf(jpegName ,"%03d.jpg" ,pic); pic++; open = 1; // signifies target jpeg file is open match = 0; // sets match back to 0 (false) so it can detect the next match to signify closing the writing image=fopen(jpegName, "w"); // write to target file image } // if file target is still open but no match, then keep writing since you're in the middle of a jpeg if (match == 0 && open == 1) { fwrite(buffer, 512, 1, image); } } fclose(file); return 0; } 

我可能会遗漏一些鲜明的东西,但是如果你要做的就是读取512字节块的文件,检查每个块的前四个八位字节是否有两个已知的前导码,并且在遇到任何一个时,打开一个图像文件并开始转储直到下一个匹配的块关闭文件并启动一个新文件,然后大约一半的发布代码不需要。

您可以使用image的值(null或不是)来指示文件是否被打开。 此外,只有在打开文件时才写入数据( image != NULL) ,如果在循环到下一个文件之前打开则关闭现有文件。

像这样的东西:

 #include  #include  #include  #include  int main(void) { // Prefixes of a jpeg file static const uint8_t jpeg1[4] = {0xff, 0xd8, 0xff, 0xe0}; static const uint8_t jpeg2[4] = {0xff, 0xd8, 0xff, 0xe1}; // open file for reading FILE* file = fopen("card.raw", "r"); // Open the file for reading if (file == NULL) { perror("card.raw"); return EXIT_FAILURE; } // target file FILE* image = NULL; // keep track of jpegs opened int pic = 0; // while there are bytes to be read in the file uint8_t buffer[512]; size_t n_bytes = 0; while( (n_bytes = fread(buffer,1, 512, file)) > sizeof(jpeg1)) { // compares first 4 bytes of buffer segment to jpeg prefixes to determine match if( memcmp(buffer, jpeg1, sizeof(jpeg1)) == 0 || memcmp(buffer, jpeg2, sizeof(jpeg2)) == 0) { // stores the jpeg file name with the # jpeg char jpegName[64]; sprintf(jpegName ,"00%d.jpg" , pic++); // match. close current file if present. if (image) fclose(image); // open new image file (sets NULL on failure) image = fopen(jpegName, "wb"); // write to target file image if (image == NULL) { perror(jpegName); break; } } // write whatever we have for our current bytes if (image) fwrite(buffer, n_bytes, 1, image); } // the above loop can exit with a file open (in fact, it is guaranteed // if we opened at least one file), so close it if one is active. if (image) fclose(image); } 

或类似的东西。 这也以二进制模式打开和关闭文件,如果它小于偶数512字节,则不会在最后一帧写入无关的垃圾。 最后,它会在每个创建的文件上增加pic ,并且具有(通常是软的)错误检查量。

无论如何,希望它有所帮助。 祝你好运。