~~~二进制文件操作~~~

vax001 2006-10-06 11:41:33

有这样一个二进制文件,大小在100M左右,里面存放了多张JPG图片,文件格式如下:

无关数据区
JPG图片数据区
无关数据区
JPG图片数据区
无关数据区
JPG图片数据区
......

已知JPG图片起始标志为:“FF D8 FF E0 00 10 4A”,结束标志为:“FF D9”。

现想把这些JPG图片数据从该文件中读出来,生成一个个单独的图片文件,该如何做呢?

恳请各位前辈高手指教,谢谢!

...全文
460 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
kingrain213 2010-05-27
  • 打赏
  • 举报
回复
不懂啊,该怎么办?
chary8088 2006-11-27
  • 打赏
  • 举报
回复
好帖子
zhucde 2006-10-08
  • 打赏
  • 举报
回复
帮你写了个程序, 测试了只含有一个图片信息的文件
int len=0;
int filesn=0;

void ReadJpg(CFile *sfp,const char *dstfile,unsigned char a,unsigned char b)
{

CFile nf;
nf.Open(dstfile,CFile::modeCreate|CFile::modeWrite|CFile::typeBinary);
unsigned t=0,t1=0;
nf.Write(&a,sizeof(char));
nf.Write(&b,sizeof(char));
while(1)
{
sfp->Read(&t,sizeof(char));
len++;
nf.Write(&t,sizeof(char));
if(t==0xFF)
{
sfp->Read(&t1,sizeof(char));
len++;
if(t1==0xD9)
break;
else
nf.Write(&t1,sizeof(char));

}

}

nf.Close();
}


调用:

void test()
{

CFile fp;
fp.Open("86b05621.jpg",CFile::modeRead|CFile::typeBinary);//文件名改一下
unsigned char a=0,b=0;
len=0;

while(1)
{
fp.Read(&a,sizeof(char));
len++;
if(len>=fp.GetLength())
break;

if(a==0xFF)
{

fp.Read(&b,sizeof(char));
len++;
if(b==0xD8)
{
filesn++;
char filename[256];
sprintf(filename,"Jpg %d.jpg",filesn);
ReadJpg(&fp,filename,a,b);
}
}

}
fp.Close();
}

思路是,先得到FF的值,然后再判断下一位是否是0xD8, 但这里要说明一下,如果你的其它数据信息里也含有FF D8值的话就会出错了, 所以为保险起见,应该再多比较几位, JPG的头是固定的,再往下就是EF E0 00 1E, 建议楼主再往下比较四位比较保险(在程序中稍作修改即可)
jixingzhong 2006-10-08
  • 打赏
  • 举报
回复
char filename[10]={0}; //jpg文件名
int file=1, flag=0, ff=0,tmp; //file是主文件名,用数字序号; flag 和ff是两个标志; tmp是读取内容
FILE *fp, *jpg; //读取文件, 以及生成文件 指针

fp = fopen("二进制文件名", "rb");
sprintf(filename, "%d.jpeg", file);
jpg = fopen(filename, "wb");

tmp = fgetc(fp);
while(tmp != EOF) //操作文件内容
{
if(tmp == 0xFF) //标记判断
{
tmp = fgetc(fp);
if(tmp == 0xD8) {flag=1; tmp = fgetc(fp);}; //开始
if(tmp == 0xD9) flag=0; //结束
}

if(flag) //是否是图片数据,是则写文件
{
if(ff) //判断是否是另外的文件, 是则重新打开一个文件
{
fclose(jpg);
file++;
sprintf(filename, "%d.jpeg", file);
jpg = fopen(filename, "wb");
}
fputc(tmp, jpg);
}
}
vax001 2006-10-08
  • 打赏
  • 举报
回复
我仔细看了文件内容,发现JPG图片起始标志也可以定为:“FF D8”,结束标志为:“FF D9”。
fairyprince 2006-10-08
  • 打赏
  • 举报
回复
你是不是在 分析某个 游戏的或程序的资源文件呀,如果是的话,这个资源文件应该配有一个 索引文件!或在其文件自身。索引可以列表索引,链表形示……
如果是你自已生成的文件包,最好加上索引,因为这样可以提高效率!
zhucde 2006-10-07
  • 打赏
  • 举报
回复
那就相对来说复杂一点了,而且看了它的起始位是7个字节,就是说还不能按int或float来读,只能两位两位的来读,所以比较繁一点.

smallbirdapple 2006-10-07
  • 打赏
  • 举报
回复
可以搜索数据,然后建立索引,作后一口气读出来,在显示
pioneer_public 2006-10-07
  • 打赏
  • 举报
回复
只有2位的读了,然后将7个组合起来,看是否是JPG的开头标记,记下此位置,然后再向后读,得到JPG的结束位置,如此保存为数组,关闭文件,再打开后,使用已知的JPG的位置,可以使用FSEEK,及FREAD将各个图片读出来了
DentistryDoctor 2006-10-07
  • 打赏
  • 举报
回复
如果它们的大小不能确定,的确不好办。
长尾巴的悟空 2006-10-07
  • 打赏
  • 举报
回复
你想反编译啊?
汇编可以解决
vax001 2006-10-06
  • 打赏
  • 举报
回复

>>>如果能够确定"无关数据区"和"JPG图片数据区"的固定大小就很方便了,

很不幸,这些数据区的大小都是不固定的,只能靠标志来定位了。

zhucde 2006-10-06
  • 打赏
  • 举报
回复
程序不难,但很复杂,就是比对.
用fread,
如果能够确定"无关数据区"和"JPG图片数据区"的固定大小就很方便了,
直接用fseek,跳到指定位置进行读取

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧