如何在不使用库的情况下获取JPEG文件的宽度/高度?[英] How to get the width/height of jpeg file without using library?

本文是小编为大家收集整理的关于如何在不使用库的情况下获取JPEG文件的宽度/高度?的处理方法,想解了如何在不使用库的情况下获取JPEG文件的宽度/高度?的问题怎么解决?如何在不使用库的情况下获取JPEG文件的宽度/高度?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

首先,我想说我多次尝试通过使用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;
     }
  }

本文地址:https://www.itbaoku.cn/post/359124.html