从文件用C提取JPEG文件 [英] Extracting jpeg files from file in C

查看:225
本文介绍了从文件用C提取JPEG文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从存储卡就像文件中提取JPEG文件。该计划将一次读取512字节的块,如果块以JPEG识别的字节开始,我的程序应该写一个输出文件的字节。它应该保持写这些字节,直到它找到另一个JPEG识别字节序列此时应立即停止写入.jpg文件,并写入到一个新的。每个文件应该被命名为00x.jpg其中x是#

我的程序编译,但不会产生所有的JPEG文件。应该有16 JPEG文件,但只生产7。

  INT主要(无效)
{
    //打开文件进行读取
    FILE *文件=的fopen(card.raw,R); //打开文件进行读取    //目标文件
    FILE *形象;    //字节的缓冲区
    uint8_t有缓冲区[512];    //检查NULL文件
    如果(文件== NULL)
    {
        FCLOSE(文件);
        的printf(无法打开文件);
        返回1;
    }    // $ P $ jpeg文件的pfixes
    uint8_t有jpeg1 [4] = {0xFF的,0xd8,为0xFF,0xe0的};
    uint8_t有JPEG2 [4] = {0xFF的,0xd8,为0xFF,0xe1};    //跟踪打开JPEG文件
    INT PIC = 0;    INT匹配= 0;    //为文件打开?
    INT开放= 0;
    //店前4个字节块
    uint8_t有检查[4];    INT byteNum;
    byteNum = FREAD(缓冲区,512,1,文件);    //同时有在文件中要读取的字节
    而(的fread(缓冲液,512,1,文件)大于0)
    {
        为(中间体X = 0; X 4;; X ++)
        {
            检查[X] =缓冲[X];
        }        //前4个字节缓冲段进行比较,以JPEG prefixes来确定匹配
        如果((memcmp(检查,jpeg1,4)== 0)||(memcmp(支票,JPEG2,4)== 0))
        {            比赛= 1;
        }
        //如果遇到一个JPEG和文件打开后,关闭该文件,并设置匹配为假
        如果(匹配== 1安培;&安培;开放式== 1)
        {
            FCLOSE(图片);
            开放= 0;
            匹配= 0;
        }        //如果比赛是真实的,文件被关闭,创建JPEG输出文件,增量PIC#,设置文件打开,比赛设置为false,打开目标文件
        如果(匹配== 1安培;&安培;开放== 0)
        {
            //商店jpegfile的名字
            炭jpegName [8];
            //存储JPEG文件名以#JPEG
            sprintf的(jpegName,%03d.jpg,PIC);
            PIC ++;
            开= 1; //表示目标JPEG文件被打开
            匹配= 0; //套匹配回0(假),因此它可以检测到下一场比赛,以表示关闭书写
            图像= FOPEN(jpegName,W); //写入到目标文件映像
        }        //如果文件的目标仍然是开放的,但没有比赛,然后继续写作,因为你在一个JPEG中间是
        如果(匹配== 0安培;&安培;开放式== 1)
        {
            FWRITE(缓冲区,512,1,图像);
        }    }    FCLOSE(文件);
    返回0;
}


解决方案

我可能失去了一些东西赤裸裸的,但如果你正在试图做的一切都在读512字节块的文件,检查每个的前四个为块两个已知的preambles,并呼吁在遇到,打开一个图像文件,并开始抛售,直到下一个匹配的块关闭该文件并启动一个新的,则不需要大约一半的贴code。

您可以使用图片(空与否)的值来决定文件是否被打开与否。此外,只有当一个文件被打开写入数据(形象!= NULL),如果循环到下一个文件打开之前关闭现有的文件。

事情是这样的:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&stdint.h GT;
#包括LT&;&string.h中GT;INT主要(无效)
{
    // $ P $ jpeg文件的pfixes
    静态常量uint8_t有jpeg1 [4] = {0xFF的,0xd8,为0xFF,0xe0的};
    静态常量uint8_t有JPEG2 [4] = {0xFF的,0xd8,为0xFF,0xe1};    //打开文件进行读取
    FILE *文件=的fopen(card.raw,R); //打开文件进行读取
    如果(文件== NULL)
    {
        PERROR(card.raw);
        返回EXIT_FAILURE;
    }    //目标文件
    FILE *图像= NULL;    //跟踪打开JPEG文件
    INT PIC = 0;    //同时有在文件中要读取的字节
    uint8_t有缓冲区[512];
    为size_t n_bytes = 0;
    而((n_bytes = FREAD(缓冲,1,512,文件))>的sizeof(jpeg1))
    {
        //前4个字节缓冲段进行比较,以JPEG prefixes来确定匹配
        如果(memcmp(缓冲,jpeg1,sizeof的(jpeg1))== 0 ||
            memcmp(缓冲,JPEG2,sizeof的(JPEG2))== 0)
        {
            //存储JPEG文件名以#JPEG
            焦炭jpegName [64];
            sprintf的(jpegName,00%D.JPG,PIC ++);            // 匹配。关闭当前文件,如果present。
            如果(图)
                FCLOSE(图片);            //打开新的图像文件(在失败时设置NULL)
            图像= FOPEN(jpegName,WB); //写入到目标文件映像
            如果(像== NULL)
            {
                PERROR(jpegName);
                打破;
            }
        }        //写什么,我们有我们目前的字节
        如果(图)
            FWRITE(缓冲,n_bytes,1,图像);
    }    //上述循环可以打开文件后退出(其实,这是保证
    //如果我们开了至少一个文件),因此,关闭它,如果一个处于活动状态。
    如果(图)
        FCLOSE(图片);
}

或类似的东西。这也打开,并在二进制模式关闭的文件,并且不写入外部垃圾加时赛的最后一帧,如果它是大于一个甚至512字节小。最后,它增加图片上创建的每个文件,并有错误检查的(诚然软)量。

不管怎样,希望它帮助。祝您好运。

I am trying to extract jpeg files from a memory-card like file. The program will read 512 byte blocks at a time and if the block starts with JPEG-identifying bytes, my program should write to an output file those bytes. It should keep writing those bytes until it finds another JPEG-identifying byte sequence at which time it should stop writing to the .jpg file and write to a new one. Each file should be named 00x.jpg where x is the #.

My program compiles but doesn't produce all the jpegs. There should be 16 JPEGs but it only produces 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;
}

解决方案

I may be missing something stark, but if all you're trying to do is read a file in 512-byte chunks, checking the first four octets of each chunk for two known preambles, and upon encountering either, open an image file and start dumping until the next chunk that matches closes the file and starts a new one, then about half the posted code isn't needed.

You can use the value of image (null or not) to dictate whether a file is opened or not. Further, only write data if a file is opened (image != NULL), and close an existing file if opened before cycling to the next file.

Something like this:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

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);
}

Or something similar. This also opens and closes files in binary-mode, and does not write extraneous junk ot the last frame if it was smaller than an even 512 bytes. Finally, it increments pic on each file created, and has a (admittedly soft) amount of error checking.

Anyway, hope it helps. Best of luck.

这篇关于从文件用C提取JPEG文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆