BMP 24 to 16

Тема в разделе "WASM.WIN32", создана пользователем jawbreaker, 1 мар 2009.

  1. jawbreaker

    jawbreaker New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2008
    Сообщения:
    6
    Хочу отконвертировать BMP-изображение из 24 бит на пиксель в 16 бит. Подскажите что я делаю неправильно при записи файла, тк его не открыть?
    Код (Text):
    1. #define RGB16(red, green, blue) ( ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3))
    2.  
    3.  
    4. void LoadBitmap()
    5. {
    6.     BITMAPINFOHEADER infoheader;
    7.     WORD             *bitmapData;
    8.     WORD             *bitmapDone;
    9.     FILE             *bitmapFile;
    10.  
    11.     BYTE             red, green, blue;
    12.  
    13.     bitmapFile = fopen("my.bmp", "rb");
    14.     fseek(bitmapFile, sizeof(BITMAPFILEHEADER), SEEK_SET);
    15.     fread(&infoheader, sizeof(BITMAPINFOHEADER), 1, bitmapFile);
    16.  
    17.     bitmapData = new WORD[infoheader.biWidth * infoheader.biHeight];
    18.     bitmapDone = new WORD[infoheader.biWidth * infoheader.biHeight];
    19.  
    20.  
    21.     for( int y=0; y<infoheader.biHeight; ++y)
    22.     {
    23.         for( int x=0; x<infoheader.biWidth; ++x)
    24.         {
    25.             fread(&blue, sizeof(BYTE), 1, bitmapFile);
    26.             fread(&green, sizeof(BYTE), 1, bitmapFile);
    27.             fread(&red, sizeof(BYTE), 1, bitmapFile);
    28.  
    29.             bitmapData[y*infoheader.biWidth + x] = RGB16(red, green, blue);
    30.         }
    31.     }
    32.  
    33.     int heightIndex = 0;
    34.     for(int y = infoheader.biHeight-1;  y>=0; --y)
    35.     {
    36.         for( int x=0; x<infoheader.biWidth; ++x)
    37.             bitmapDone[heightIndex*infoheader.biWidth + x] = bitmapData[y*infoheader.biWidth + x];
    38.  
    39.         ++heightIndex;
    40.     }
    41.  
    42.     BITMAPFILEHEADER bfh;
    43.     memset (&bfh, 0, sizeof(bfh));
    44.     bfh.bfType = 0x4D42;                                   
    45.     bfh.bfOffBits = sizeof(bfh) + sizeof(infoheader) + 1024;       
    46.     bfh.bfSize = bfh.bfOffBits +
    47.         2*sizeof(BYTE) * infoheader.biWidth * infoheader.biHeight +
    48.         infoheader.biHeight * ((2*sizeof(BYTE) * infoheader.biWidth) % 4);
    49.  
    50.     FILE *pFile = fopen("cool.bmp", "wb");
    51.  
    52.     UINT nWrittenFileHeaderSize = fwrite(&bfh, 1,
    53.         sizeof(BITMAPFILEHEADER), pFile);
    54.  
    55.     //fwrite(, , )
    56.     UINT nWrittenInfoHeaderSize = fwrite(&infoheader,
    57.         1, sizeof(BITMAPINFOHEADER), pFile);
    58.    
    59.     for( int y=0; y<infoheader.biHeight; ++y)
    60.     {
    61.         for( int x=0; x<infoheader.biWidth; ++x)
    62.         {
    63.             fwrite(&bitmapDone[y*infoheader.biWidth + x], 2*sizeof(BYTE), 1, pFile);
    64.         }
    65.     }
    66.  
    67. }
     
  2. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    jawbreaker

    спрашиваешь ты, показывая нам

     
  3. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    jawbreaker
    1) Зачем ты считываешь и записываешь растр попиксельно? Пиши сразу
    Код (Text):
    1. WriteFile(pFile,&bitmapDone,infoheader.biWidth*infoheader.biHeight<<1,&numBytes,0);
    2) Не хватает Этой строки
    Код (Text):
    1. infoheader.biBitCount=16
    3) Я не знаю C, но похоже ты перепутал 2 и 3 параметр в fwrite

    Сравни это:
    fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), pFile);
    fwrite(&infoheader, 1, sizeof(BITMAPINFOHEADER), pFile);
    и это:
    fwrite(&bitmapDone[y*infoheader.biWidth + x], 2*sizeof(BYTE), 1, pFile);

    Добавлено:
    4) Не понял зачем отражать изображение по вертикали?
    Код (Text):
    1. bitmapDone[heightIndex*infoheader.biWidth + x] = bitmapData[y*infoheader.biWidth + x];
    5) Кажется преобразовать в RGB16 можно, разделив 24 битное число на  31.6160499759731 
    то есть
    Код (Text):
    1. RGB16=round(RGB24/31.6160499759731);
     
  4. jawbreaker

    jawbreaker New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2008
    Сообщения:
    6
    murder
    Спасибо за помощь!
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    murder
    так как возращаемые значения не проверяются, то монописсуально какой порядок 2 и 3 аргументов.