/* * bmpFromRimage.cpp * * Copyright (c) 2008 Machine Perception Laboratory * University of California San Diego. * * Authors: Andrew Salamon * */ #include "bmpFromRimage.h" #include #include #ifdef WIN32 #ifndef WINVER #define WINVER 0x0502 #endif #include "afxwin.h" #endif #include "rimage.h" bool WriteDIB( const char *szFile, BITMAPINFO *bmi, HBITMAP hDIB, std::vector &data ); #define BITS 24 bool writeRimageAsBMP( const RImage &image, const std::string &filename ) { unsigned int width = image.width; unsigned int height = image.height; unsigned int count = width * height * 3; // BMPs need to be padded to 32 bit boundaries, which we don't do. // ASSERT( (width % 32) == 0 ); std::vector buf( count, 0 ); BYTE *data = &buf.front(); for( unsigned int y = 0; y < height; y++ ) { for( unsigned int x=0; x < width; x++ ) { BYTE val = (BYTE)(image.getPixel( x, y ) * 255.0); int yoff = ((height-1) - y) * (width * 3); // We probably ought to be transforming the rgb values inversely to the way // we transform them when we convert from a bmp to a rimage. data[ (x*3) + yoff ] = val; data[ (x*3) + 1 + yoff ] = val; data[ (x*3) + 2 + yoff ] = val; } } BITMAPINFO *bmi; SIZE_T bmiSize = sizeof(BITMAPINFOHEADER); // + (sizeof(RGBQUAD)<bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi->bmiHeader.biWidth = width; bmi->bmiHeader.biHeight = height; bmi->bmiHeader.biPlanes = 1; bmi->bmiHeader.biBitCount = BITS; bmi->bmiHeader.biCompression = BI_RGB; bmi->bmiHeader.biSizeImage = (((width * BITS + 31) & ~31) >> 3) * abs((int)height); // bmi->bmiHeader.biClrImportant = bmi->bmiHeader.biClrUsed = (1 << BITS); // initialize grayscale palette /* for( int i=0; i<256; i++ ) { bmi->bmiColors[ i ].rgbRed = bmi->bmiColors[ i ].rgbGreen = bmi->bmiColors[ i ].rgbBlue = (BYTE)i; } */ void *ptr; HBITMAP dib; HDC hdc; hdc = ::GetDC(0); dib = ::CreateDIBSection(hdc,bmi,DIB_RGB_COLORS,&ptr,0,0); ::SetDIBits(hdc,dib,0,height,data,bmi,DIB_RGB_COLORS); ::ReleaseDC(0,hdc); // use the code above and Attach() the HBITMAP to your CBitmap ... // CBitmap m_bitmap; // m_bitmap.Attach( dib ); // now how to write it to a file? bool res = WriteDIB( filename.c_str(), bmi, dib, buf ); delete []bmi; return res; } // WriteDIB - Writes a DIB to file // Returns - TRUE on success // szFile - Name of file to write to // hDIB - Handle of the DIB bool WriteDIB( const char *szFile, BITMAPINFO *bmi, HBITMAP hDIB, std::vector &data ) { BITMAPFILEHEADER hdr; if (!hDIB) return false; CFile file; if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) ) return false; int nColors = 1 << bmi->bmiHeader.biBitCount; // Fill in the fields of the file header hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM" hdr.bfSize = GlobalSize (hDIB) + sizeof( hdr ); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; hdr.bfOffBits = (DWORD) (sizeof( hdr ) + bmi->bmiHeader.biSize); // + nColors * sizeof(RGBQUAD)); // Write the file header file.Write( &hdr, sizeof(hdr) ); // Write the DIB header and the bits int bmiSize; bmiSize = sizeof(BITMAPINFOHEADER); // + (sizeof(RGBQUAD)<