问题描述
首先,我想说我多次尝试通过使用Google搜索来找到答案,我发现了很多结果,但我不明白,因为我不知道读取二进制文件的想法,并转换了值获得可读值.
我尝试做的事情.
unsigned char fbuff[16]; FILE *file; file = fopen("C:\\loser.jpg", "rb"); if(file != NULL){ fseek(file, 0, SEEK_SET); fread(fbuff, 1, 16, file); printf("%d\n", fbuff[1]); fclose(file); }else{ printf("File does not exists."); }
我想要一个简单的解释,其中显示了如何从其标题中获取JPEG文件的宽度/高度,然后将该值转换为可读值.
推荐答案
不幸的是,对于JPEG而言,它似乎并不简单.您应该查看 jhead 命令行工具.它提供了此信息.通过源时,您将看到函数ReadJpegSections.此函数通过JPEG文件中包含的所有片段进行扫描以提取所需的信息.处理具有SOFn标记的帧时,将获得图像宽度和高度.
我看到源位于公共领域中,所以我将显示获取图像信息的摘要:
static int Get16m(const void * Short) { return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1]; } static void process_SOFn (const uchar * Data, int marker) { int data_precision, num_components; data_precision = Data[2]; ImageInfo.Height = Get16m(Data+3); ImageInfo.Width = Get16m(Data+5);
从源代码中,对我来说很明显,此信息没有单个"标头".您必须通过JPEG文件进行扫描,对每个细分细分进行解析,直到找到所需的信息为止.这在 wikipedia文章:
jpeg图像由一系列段组成,每个片段以标记开始,每个片段以0xff字节开始,然后是一个字节,指示它是什么样的标记.一些标记仅由这两个字节组成;其他则是两个字节,指示以下标记特定有效载荷数据的长度.
JPEG文件由一系列段组成:
SEGMENT_0 SEGMENT_1 SEGMENT_2 ...
每个段以2字节标记开始.第一个字节为0xFF,第二个字节确定段的类型.接下来是对段长度的编码.该段内的数据是特定于该段类型的数据.
在类型SOFn的段或"帧开始[n]"的段中找到图像宽度和高度,其中" n"是一些数字,对JPEG解码器意味着特殊的东西.它应该足够好,只能寻找SOF0,并且其字节名称为0xC0.找到此框架后,您可以解码以找到图像高度和宽度.
因此,程序的结构要做您想像的外观:
file_data = the data in the file data = &file_data[0] while (data not at end of file_data) segment_type = decoded JPEG segment type at data if (type != SOF0) data += byte length for segment_type continue else get image height and width from segment return
这本质上是 Michael Petrov的get_jpeg_size()实施.
其他推荐答案
然后,您必须找到[FFC0]的JPEG的高宽标记.
在二元甲酸甲酸盐中找到FFC0后,四个字节是hight,六个字节和七个字节是宽度.
eg: [ff c0] d8 c3 c2 [ff da] [00 ff] | | | | ->height ->width int position; unsigned char len_con[2]; /*Extract start of frame marker(FFC0) of width and hight and get the position*/ for(i=0;i<FILE_SIZE;i++) { if((image_buffer[i]==FF) && (image_buffer[i+1]==c0) ) { position=i; } } /*Moving to the particular byte position and assign byte value to pointer variable*/ position=position+5; *height=buffer_src[position]<<8|buffer_src[position+1]; *width=buffer_src[position+2]<<8|buffer_src[position+3]; printf("height %d",*height); printf("width %d",*width);
其他推荐答案
问题是旧的,其他答案是正确的,但它们的格式不是最简单的.我只是使用getc快速获得尺寸,同时跳过无关标记(它也支持渐进的JPEGS ):
int height, width; // start of image (SOI) getc(f); // oxff getc(f); // oxd8 // Scan miscellaneous markers until we reach SOF0 marker (0xC0) for(;;) { // next marker int marker; while((marker = getc(f)) != 0xFF); while((marker = getc(f)) == 0xFF); // SOF if (marker == 0xC0 || marker == 0xC2) { getc(f); // length (2 bytes) getc(f); // # getc(f); // bpp, usually 8 height = (getc(f) << 8) + getc(f); // height width = (getc(f) << 8) + getc(f); // width break; } }