2012-04-11 2 views
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; 
} 

возврата всегда х == 26112 и у == 30825 для всех изображений любого типа и любого разрешения

Я скомпилирован с VS 2010 SP1 на Win7 x64

Update

Я пытаюсь открыть jpg-файлы, которые были созданы Photshop. Photshop закодировать JPEG файлы с Exif Metadata

Debugger шоу (правая кнопка мыши на полноразмерный)

enter image description here

так код теперь посмотрите:

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); 
     } 
    } 
+0

Вы помечено это как C++. По крайней мере, используйте такие вещи, как 'string' и' fstream', которые не являются C. – chris

+0

Рассмотрите возможность использования GIL: http://www.boost.org/doc/libs/1_49_0/libs/gil/doc/index.html –

+0

Хотя это код C-стиля, нет ничего плохого в том, что он помечен как C++, поскольку он/она может принимать решения (например, связанные с larsmans), которые подходят для среды C++, несмотря на то, что здесь написано крошечный фрагмент кода, , Кроме того, нет смысла обсуждать ее стиль кодирования, и не слишком много причин для этого. – Kaganar

ответ

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 не изменяются вообще! И может быть, вы никогда не инициализировали x и y в своей функции вызова и, следовательно, показывали какой-то мусор?

PS: Я скомпилировал с gcc 4.6.1 MinGW на Windows 7

+0

У меня такой же код выполнения. Я пытаюсь инициализировать x и y перед добавлением к func, 2) проверять x, y vals в элементе GetImageSizeEx, 3) проверять fopen и путь к файлу и т. Д. Всегда всегда x == 26112 и y == 30825. PS Я скомпилирован с VS 2010 SP1 на Win7 x64 – mola10

+1

@ mola10 Отладчик - ваш последний вариант. И если действительно gcc и VS ведут себя по-другому, то нам есть чему поучиться здесь –