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

3 つの形式すべてでコードを実行しましたが、さまざまな解像度で問題なく動作します。私が提案する唯一のことは、GetImageSizeEx適切に呼び出すことです(バックスラッシュをエスケープします)

何かのようなもの

int x,y;

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

あなたが気づいたfopenいくつかの失敗のケースは、間違ったファイル名などのためにそれ自体が失敗していて、内部で変更されてxいない可能性があります。または、間違ったファイルを読み込んで、適切なヘッダーを読み取ることができず、したがって再び、まったく変更されない別のケースです! また、呼び出し元の関数で初期化されていないため、ゴミが表示されている可能性がありますか?yGetImageSizeExxyxy

PSgcc 4.6.1Windows 7でmingwでコンパイルしました

于 2012-04-11T19:12:58.393 に答える