2

我正在尝试使用此代码从文件中获取图像分辨率

bool GetImageSizeEx(const char *fn, int *x,int *y)
{ 
    FILE *f=fopen(fn,"rb"); 

    if (f==0) return false;

    fseek(f,0,SEEK_END); 
    long len=ftell(f); 
    fseek(f,0,SEEK_SET); 

    if (len<24) {
        fclose(f); 
        return false;
    }

  // Strategy:
  // reading GIF dimensions requires the first 10 bytes of the file
  // reading PNG dimensions requires the first 24 bytes of the file
  // reading JPEG dimensions requires scanning through jpeg chunks
  // In all formats, the file is at least 24 bytes big, so we'll read that always
    unsigned char buf[24]; fread(buf,1,24,f);


  // For JPEGs, we need to read the first 12 bytes of each chunk.
  // We'll read those 12 bytes at buf+2...buf+14, i.e. overwriting the existing buf.
    if (buf[0]==0xFF && buf[1]==0xD8 && buf[2]==0xFF && buf[3]==0xE0 && buf[6]=='J' && buf[7]=='F' && buf[8]=='I' && buf[9]=='F')
    {
        long pos=2;
        while (buf[2]==0xFF)
        {
            if (buf[3]==0xC0 || buf[3]==0xC1 || buf[3]==0xC2 || buf[3]==0xC3 || buf[3]==0xC9 || buf[3]==0xCA || buf[3]==0xCB) 
                break;

            pos += 2+(buf[4]<<8)+buf[5];
            if (pos+12>len) break;
            fseek(f,pos,SEEK_SET); 
            fread(buf+2,1,12,f);   
        }
    }


    fclose(f);

  // JPEG: (first two bytes of buf are first two bytes of the jpeg file; rest of buf is the DCT frame
    if (buf[0]==0xFF && buf[1]==0xD8 && buf[2]==0xFF)
    {     
        *y = (buf[7]<<8) + buf[8]; 
        *x = (buf[9]<<8) + buf[10]; 

        return true;
    }

  // GIF: first three bytes say "GIF", next three give version number. Then dimensions
    if (buf[0]=='G' && buf[1]=='I' && buf[2]=='F')
    { 
        *x = buf[6] + (buf[7]<<8);
        *y = buf[8] + (buf[9]<<8);
        return true;
    }

  // PNG: the first frame is by definition an IHDR frame, which gives dimensions
    if ( buf[0]==0x89 && buf[1]=='P' && buf[2]=='N' && buf[3]=='G' && buf[4]==0x0D && buf[5]==0x0A && buf[6]==0x1A && buf[7]==0x0A && buf[12]=='I' && buf[13]=='H' && buf[14]=='D' && buf[15]=='R')
    {
        *x = (buf[16]<<24) + (buf[17]<<16) + (buf[18]<<8) + (buf[19]<<0);
        *y = (buf[20]<<24) + (buf[21]<<16) + (buf[22]<<8) + (buf[23]<<0);

        return true;
    }

    return false;
}

对于任何类型和任何分辨率的所有图像,始终返回 x == 26112 和 y == 30825

我在 Win7 x64 上使用 VS 2010 SP1 编译

更新

我正在尝试打开由 Photoshop 创建的 jpg 文件。Photoshop 使用 Exif 元数据对 JPEG 文件进行编码

调试器显示(右键单击以放大)

在此处输入图像描述

所以现在看代码:

if ((buf[0]==0xFF && buf[1]==0xD8 && buf[2]==0xFF && buf[3]==0xE0 && buf[6]=='J' && buf[7]=='F' && buf[8]=='I' && buf[9]=='F') ||
        (buf[0]==0xFF && buf[1]==0xD8 && buf[2]==0xFF && buf[3]==0xE1 && buf[6]=='E' && buf[7]=='x' && buf[8]=='i' && buf[9]=='f'))
    {
        long pos=2;
        while (buf[2]==0xFF)
        {
            if (buf[3]==0xC0 || buf[3]==0xC1 || buf[3]==0xC2 || buf[3]==0xC3 || buf[3]==0xC9 || buf[3]==0xCA || buf[3]==0xCB) 
                break;

            pos += 2+(buf[4]<<8)+buf[5];
            if (pos+12>len) break;
            fseek(f,pos,SEEK_SET); 
            fread(buf+2,1,12,f);   
        }
    }
4

1 回答 1

2

我为所有三种格式运行了您的代码,它在各种分辨率下都运行良好!我唯一建议的就是GetImageSizeEx适当地打电话给你(转义反斜杠)

就像是

int x,y;

GetImageSizeEx("C:\\Users\\IBM_ADMIN\\Desktop\\pavan2.png", &x, &y);
printf("%d %d", x, y );

您注意到的一些可能的失败情况可能fopen是由于某些错误的文件名等而导致自身失败,x并且y从未在内部进行修改GetImageSizeEx。或者在另一种情况下,您读取了错误的文件并且您无法读取适当的标题,因此再次读取,x并且y根本没有被修改!并且可能您从未初始化xy在您的调用函数中,因此显示了一些垃圾?

PSgcc 4.6.1 :我在 Windows 7 上用 mingw 编译它

于 2012-04-11T19:12:58.393 回答