示例#1
0
	void LoadRGBAImage(TEXTURE_RGBA& tex, string Filename, string MkFilename) {
		unsigned char col[3];
		unsigned int ind = 0;
		TEXTURE_RGBA& bitmap = tex; //返回位图
		bitmap.buffer = nullptr; bitmap.sizeX = bitmap.sizeY = 0;
		std::ifstream bmpfile(Filename, std::ios::binary | std::ios::in); //位图文件(二进制)
		std::ifstream maskfile(MkFilename, std::ios::binary | std::ios::in); //遮罩位图文件(二进制)
		if (!bmpfile.is_open()) {
			printf("[console][Warning] Cannot load %s\n", Filename.c_str());
			return;
		}
		BITMAPFILEHEADER bfh; //各种关于文件的参数
		BITMAPINFOHEADER bih; //各种关于位图的参数
							  //开始读取
		maskfile.read((char*)&bfh, sizeof(BITMAPFILEHEADER)); //这两个是占位mask文件的
		maskfile.read((char*)&bih, sizeof(BITMAPINFOHEADER)); //到了后面mask可以直接从颜色部分开始读取
		bmpfile.read((char*)&bfh, sizeof(BITMAPFILEHEADER)); //真正的info以这个bmp文件为准
		bmpfile.read((char*)&bih, sizeof(BITMAPINFOHEADER)); //它将覆盖之前从mask文件读出来的info数据
		bitmap.sizeX = bih.biWidth;
		bitmap.sizeY = bih.biHeight;
		bitmap.buffer = unique_ptr<ubyte[]>(new unsigned char[bitmap.sizeX * bitmap.sizeY * 4]);
		bool noMaskFile = MkFilename == "";
		for (unsigned int i = 0; i < bitmap.sizeX * bitmap.sizeY; i++) {
			//把BGR格式转换为RGB格式
			bmpfile.read((char*)col, 3);
			bitmap.buffer[ind++] = col[2]; //R
			bitmap.buffer[ind++] = col[1]; //G
			bitmap.buffer[ind++] = col[0]; //B
			if (noMaskFile) {
				bitmap.buffer[ind++] = 255;
			}
			else {
				//将遮罩图的红色通道反相作为Alpha通道
				maskfile.read((char*)col, 3);
				bitmap.buffer[ind++] = 255 - col[2]; //A
			}
		}
		bmpfile.close();
		maskfile.close();
	}
void SaveBMP ( const char * szFile, CRaster bmp, int temp_i )
{
    BITMAPFILEHEADER bmfh;

    bmfh.bfType='MB',                                 //PALETTE
    bmfh.bfSize = ( sizeof(bmfh) + sizeof(BITMAPINFO) + 1024 + (bmp.Width*bmp.Height));//quizas -4
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfOffBits =  1078;


	BITMAPINFOHEADER bmih = bmp.pbmi->bmiHeader;

    // Open file.
	ofstream bmpfile (szFile , ios::out | ios::binary);

	if (! bmpfile.is_open())
        cout << "ERROR SAVING FILE" << endl;		// Error opening file

	//Save bitmap fileheader & infoheader
	bmpfile.write ((char*)&bmfh,sizeof (BITMAPFILEHEADER));
	bmpfile.write ((char*)&bmih,sizeof (BITMAPINFOHEADER));

    int i, j;
    for( i = 0; i < 256; i++ ){
    bmpfile.write ((char*)&bmp.Palette[i], sizeof(char)*4);
    }

    //Save the data
    for( i = (bmp.Height-1); i >= 0; i-- )
        for( j = 0; j < bmp.Width+temp_i; j++ )
        {
             bmpfile.write ((char*)&bmp.Raster[i][j], sizeof(char));
        }

	bmpfile.close();
}
示例#3
0
文件: qImage.hpp 项目: qiangd6/QTK
			///
			/// LDR I/O, only available to LDR images
			void SaveBmp(const std::string& file_name)
			{
				BOOST_STATIC_ASSERT( (boost::is_same<T, UCHAR>::value) );
				BOOST_STATIC_ASSERT( channel == 3 );

				size_t pos = file_name.find_last_of(".");
				std::string file_type = file_name.substr(++pos, std::string::npos);
				boost::to_lower(file_type);
				assert(file_type == "bmp");

				// create output file
				ofstream bmpfile(file_name.c_str(), ios::out | ios::binary);
				if(!bmpfile) 
				{
					assert(0);
					return;
				}

				// save bitmap file header
				BITMAPFILEHEADER fileHeader;
				memset(&fileHeader, 0, sizeof(BITMAPFILEHEADER));
				fileHeader.bfType = 0x4d42;
				fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

				if(!bmpfile.write((char*)&fileHeader, sizeof(fileHeader)))
				{
					assert(0);
					bmpfile.close();
					return;
				}

				// save bitmap info header
				BITMAPINFOHEADER infoHeader;
				memset(&infoHeader, 0, sizeof(BITMAPINFOHEADER));
				infoHeader.biSize = sizeof(infoHeader);
				infoHeader.biWidth = GetWidth();
				infoHeader.biHeight = GetHeight();
				infoHeader.biPlanes = 1;
				infoHeader.biBitCount = sizeof(UCHAR)*GetChannel()*8;
				infoHeader.biCompression = BI_RGB;

				if(!bmpfile.write((char*)&infoHeader, sizeof(infoHeader)))
				{
					assert(0);
					bmpfile.close();
					return;
				}

				UCHAR * swap_channel_data = new UCHAR[GetWidth() * GetHeight() * GetChannel()];
				memcpy(swap_channel_data, GetData(), GetWidth() * GetHeight() * GetChannel());
				for (UINT i = 0; i < GetWidth() * GetHeight() * GetChannel(); i += GetChannel())
					swap(swap_channel_data[i], swap_channel_data[i + 2]);

				// save bitmap data
				if(!bmpfile.write((char*)swap_channel_data, GetWidth() * GetHeight() * GetChannel()))
				{
					assert(0);
					bmpfile.close();
					return;
				}

				delete[] swap_channel_data;
				bmpfile.close();
			}
// **********
// CRaster::LoadBMPFile (FileName);
//   - loads a BMP file into a CRaster object
//   * supports non-RLE-compressed files of 1, 2, 4, 8 & 24 bits-per-pixel
void CRaster::LoadBMP (char * szFile)
{
    BITMAPFILEHEADER bmfh;
    BITMAPINFOHEADER bmih;

    // Open file.
    ifstream bmpfile (szFile , ios::in | ios::binary);

    if (! bmpfile.is_open())
    {
        cout << "ERROR OPENING FILE" << endl;		// Error opening file
        system("PAUSE");
    }

    // Load bitmap fileheader & infoheader
    bmpfile.read ((char*)&bmfh,sizeof (BITMAPFILEHEADER));
    bmpfile.read ((char*)&bmih,sizeof (BITMAPINFOHEADER));

    // Check filetype signature
    if (bmfh.bfType!='MB')
    {
        cout << "ERROR FILE IS NOT BMP" << endl;		// File is not BMP
        system("PAUSE");
    }
    // Assign some short variables:
    BPP=bmih.biBitCount;      //bits per pixel
    if ( BPP != 8 )
    {
        cout << "ERROR THE BMP FILE SHOULD BE 8 BPP" << endl;
        system("PAUSE");
    }
    Width=bmih.biWidth;
    Height= (bmih.biHeight>0) ? bmih.biHeight : -bmih.biHeight; // absoulte value
    BytesPerRow = Width * BPP / 8;
    BytesPerRow += (4-BytesPerRow%4) % 4;	// int alignment

    // If BPP aren't 24, load Palette:
    if (BPP==24) pbmi=(BITMAPINFO*)new char [sizeof(BITMAPINFO)];
    else
    {
        pbmi=(BITMAPINFO*) new char[sizeof(BITMAPINFOHEADER)+(1<<BPP)*sizeof(RGBQUAD)];
        Palette=(RGBQUAD*)((char*)pbmi+sizeof(BITMAPINFOHEADER));
        bmpfile.read ((char*)Palette,sizeof (RGBQUAD) * (1<<BPP));
    }
    pbmi->bmiHeader=bmih;

    // Load Raster
    bmpfile.seekg (bmfh.bfOffBits,ios::beg);

//	Raster= new char[BytesPerRow*Height];

//COMIENZO
    int i, bitwidth;

    bitwidth = ((BytesPerRow / sizeof(char)));
    if((BytesPerRow % sizeof(char) > 0 ))
        bitwidth++;
//    cout << bitwidth << endl;
//    system("PAUSE");
//start
    //se reserva memoria para las filas
    Raster = new char*[Height];

    //se reserva memoria para las columnas
    for( i = 0; i <= Width; i++ )
        Raster[i] = new char[Width];
//end     FIN


    //El problema ESTA AQUI!!!!
    // (if height is positive the bmp is bottom-up, read it reversed)
    if (bmih.biHeight>0)                               //NO SE DE ESTAS LINEAS
        for (int n=Height-1; n>=0; n--)
            bmpfile.read (Raster[n],BytesPerRow);
    else                                               //NO SE DE ESTAS LINEAS
        bmpfile.read (Raster,BytesPerRow*Height);      //NO SE DE ESTAS LINEAS

    // so, we always have a up-bottom raster (that is negative height for windows):
    pbmi->bmiHeader.biHeight=-Height;

    bmpfile.close();


    cout << "SIZE OF THE BMP ---> " << ( sizeof(bmfh) + sizeof(BITMAPINFO) + 1024 + (Width*Height)-4) << endl;
//    system("PAUSE");
}
示例#5
0
			/**
			 * BMPImage::LoadBMPFile (FileName);
			 *  - loads a BMP file into a BMPImage object
			 *  - supports non-RLE-compressed files of 1, 2, 4, 8 & 24 bits-per-pixel
			 *  - requires power of two bitmap. yes really. otherwise wonky rendering!
			 **/
			int BMPImage::LoadBMP (const char* szFile)
			{
				#if defined(ARK2D_MACINTOSH)
					ErrorDialog::createAndShow(StringUtil::append("Loading bitmaps is broken on Mac: ", string(szFile)));
					exit(0);
				#endif

				ARK2D_BITMAPFILEHEADER bmfh;
				ARK2D_BITMAPINFOHEADER bmih;

				// Open file.
				ifstream bmpfile (szFile , ios::in | ios::binary);
				if (! bmpfile.is_open()) return 1;		// Error opening file


				// Load bitmap fileheader & infoheader
				bmpfile.read ((char*)&bmfh, sizeof (ARK2D_BITMAPFILEHEADER));
				bmpfile.read ((char*)&bmih, sizeof (ARK2D_BITMAPINFOHEADER));

				// Check filetype signature
				//if (bmfh.bfType != 'MB') return 2;		// File is not BMP

				char* first = (char*) &bmfh.bfType;
				if ((*first) != 'M') return 2;	// File is not BMP
				if ((*first+1) != 'B') return 2;	// File is not BMP

				// Assign some short variables:
				BPP = bmih.biBitCount;
				Width = bmih.biWidth;
				Height = (bmih.biHeight>0) ? bmih.biHeight : -bmih.biHeight; // absoulte value
				BytesPerRow = Width * BPP / 8;
				BytesPerRow += (4-BytesPerRow%4) % 4;	// int alignment

				// If BPP aren't 24, load Palette:
				if (BPP==24) pbmi=(ARK2D_BITMAPINFO*)new char [sizeof(ARK2D_BITMAPINFO)];
				else
				{
					pbmi=(ARK2D_BITMAPINFO*) new char[sizeof(ARK2D_BITMAPINFOHEADER)+(1<<BPP)*sizeof(ARK2D_RGBQUAD)];
					Palette=(ARK2D_RGBQUAD*)((char*)pbmi+sizeof(ARK2D_BITMAPINFOHEADER));
					bmpfile.read ((char*)Palette,sizeof (ARK2D_RGBQUAD) * (1<<BPP));
				}
				pbmi->bmiHeader=bmih;

				// Load Raster
				bmpfile.seekg (bmfh.bfOffBits, ios::beg);

				Raster = new char[BytesPerRow*Height];

				// (if height is positive the bmp is bottom-up, read it reversed)
				if (bmih.biHeight>0)
					for (int n=Height-1;n>=0;n--)
						bmpfile.read (Raster+BytesPerRow*n,BytesPerRow);
				else
					bmpfile.read (Raster,BytesPerRow*Height);

				// so, we always have a up-bottom raster (that is negative height for windows):
				pbmi->bmiHeader.biHeight=-Height;

				bmpfile.close();

				return 0;
			}
示例#6
0
// ****************************************************************************
// * SaveBMP                                                                  *
// *   Save the content of a C_Image object into a BMP file                   *
// *                        (c) Sept2000, Juan Soulie <*****@*****.**> *
// ****************************************************************************
int C_Image::SaveBMP (char * szFileName)
{
	int n;

	// Create file.
	ofstream bmpfile (szFileName , ios::out | ios::binary | ios::trunc);
	if (! bmpfile.is_open()) { ERRORMSG("Error creating file"); return 0;}

	// determine BPP for file:
	int SaveBPP;
	if (BPP == 1) SaveBPP=1;
	else if (BPP <= 4) SaveBPP=4;
	else if (BPP <= 8) SaveBPP=8;
	else SaveBPP=24;

	// *1* SAVE BITMAP FILE HEADER
	struct BITMAPFILEHEADER {
		unsigned short	bfType; 
		unsigned long	bfSize; 
		unsigned short	bfReserved1; 
		unsigned short	bfReserved2; 
		unsigned long	bfOffBits; 
	} bmfh;

	bmfh.bfType='MB';
	bmfh.bfSize=0;	// TO DO
	bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
	bmfh.bfOffBits = 54 + ((SaveBPP==24) ? 0 : (1<<SaveBPP)*4);
	bmpfile.write ((char*)&bmfh,sizeof (bmfh));

	// *2* SAVE BITMAP INFO HEADER
	struct BITMAPINFOHEADER {
		unsigned long  biSize;
		         long  biWidth;
		         long  biHeight;
		unsigned short biPlanes;
		unsigned short biBitCount;
		unsigned long  biCompression;
		unsigned long  biSizeImage;
		         long  biXPelsPerMeter;
		         long  biYPelsPerMeter;
		unsigned long  biClrUsed;
		unsigned long  biClrImportant;
	} bmih;

	bmih.biSize=sizeof(bmih);
	bmih.biWidth=Width;
	bmih.biHeight=Height;	// down-top
	bmih.biPlanes=1;
	bmih.biBitCount=SaveBPP;
	bmih.biCompression=0;// BI_RGB?
	bmih.biSizeImage =(Width*BPP)/8;
	bmih.biSizeImage += (4- (bmih.biSizeImage)%4)%4;
	bmih.biXPelsPerMeter=11811;
	bmih.biYPelsPerMeter=11811;
	bmih.biClrUsed=0;
	bmih.biClrImportant=0;

	bmpfile.write ((char*)&bmih,sizeof (bmih));

	// *3* IF BPP AREN'T 24, SAVE PALETTE.
	if (BPP!=24)
	{
		for (n=0;n< 1<<BPP;n++)
		{
			bmpfile.put(Palette[n].b);
			bmpfile.put(Palette[n].g);
			bmpfile.put(Palette[n].r);
			bmpfile.put((char)0);
		}
		for (;n < 1<<SaveBPP; n++)	// in case SaveBPP is higher than BPP
			bmpfile.write((char*)'\0\0\0\0',4);
	}

	// *4* SAVE RASTER DATA

	int PixelsPerByte = 8/SaveBPP;	//used only if BPP are less than 8
	int BitMask = (1<<SaveBPP)-1;	//used only if BPP are less than 8

	// Raster Data Rows are 32bit aligned in BMP files.
	int RowAlignmentInFile = ((4- ((Width*SaveBPP+7)/8)%4)%4); // (bytes)
	for (int row=0; row<Height; row++)
	{
		char * pPixel;
		// If height is positive the bmp is bottom-up, set adequate row info:
		pPixel= (char*) Raster + BytesPerRow *
			( (bmih.biHeight>0)? Height-row-1 : row );

		if (SaveBPP >= 8)	// 8 or more BPP: Save as block.
			bmpfile.write (pPixel, Width*SaveBPP/8);

		else				// Less than 8BPP: Save packing bytes.
		{
			unsigned char charToPut;
			for (int col=0; col < Width; col+=PixelsPerByte)
			{
				charToPut=0;
				for (int bit=8 ; bit >0 ; bit -= BPP)	// high to low
					charToPut |= (*pPixel++ & BitMask) << (bit - BPP);
				bmpfile.put(charToPut);
			}
		}
		// Ignore aligment bytes of file:
		for (int m=0; m<RowAlignmentInFile; m++) bmpfile.put ((char)0);
	}


	bmpfile.close();
	return 1;

}
示例#7
0
// ****************************************************************************
// * LoadBMP                                                                  *
// *   Load a BMP File into the C_Image object                                *
// *                        (c) Sept2000, Juan Soulie <*****@*****.**> *
// ****************************************************************************
int C_Image::LoadBMP (char* szFileName)
{
	int n;

	// Open file.
	ifstream bmpfile (szFileName , ios::in | ios::binary | ios::nocreate);
	if (! bmpfile.is_open()) { ERRORMSG("File not found"); return 0; }

	// *1* LOAD BITMAP FILE HEADER
	struct BITMAPFILEHEADER {
		unsigned short	bfType; 
		unsigned long	bfSize; 
		unsigned short	bfReserved1; 
		unsigned short	bfReserved2; 
		unsigned long	bfOffBits; 
	} bmfh;
	bmpfile.read ((char*)&bmfh,sizeof (bmfh));

	// Check filetype signature
	if (bmfh.bfType!='MB') { ERRORMSG("Not a valid BMP File"); return 0; }

	// *2* LOAD BITMAP INFO HEADER
	struct BITMAPINFOHEADER {
		unsigned long  biSize;
		         long  biWidth;
		         long  biHeight;
		unsigned short biPlanes;
		unsigned short biBitCount;
		unsigned long  biCompression;
		unsigned long  biSizeImage;
		         long  biXPelsPerMeter;
		         long  biYPelsPerMeter;
		unsigned long  biClrUsed;
		unsigned long  biClrImportant;
	} bmih;
	bmpfile.read ((char*)&bmih,sizeof (bmih));

	// Check for supported Color depths
	if ((bmih.biBitCount!=1) &&
		(bmih.biBitCount!=4) &&
		(bmih.biBitCount!=8) &&
		(bmih.biBitCount!=24))
		{ ERRORMSG("Color depth not supported"); return 0; }

	// Check if file is compressed
	if (bmih.biCompression!=0) 
		{ ERRORMSG("File uses unsupported compression"); return 0; }

	// Set: Allocate memory to contain Data
	Init (bmih.biWidth,
		(bmih.biHeight>0) ? bmih.biHeight: -bmih.biHeight,	// abs
		bmih.biBitCount);

	// *3* IF BPP AREN'T 24, LOAD PALETTE.
	if (BPP!=24)
	{
		for (n=0;n< 1<<BPP;n++)
		{
			Palette[n].b=bmpfile.get();
			Palette[n].g=bmpfile.get();
			Palette[n].r=bmpfile.get();
			bmpfile.get();	// 4th byte of RGBQUAD discarded
		}
	}

	// *4* LOAD RASTER DATA

	// Seek Raster Data in file
	bmpfile.seekg (bmfh.bfOffBits,ios::beg);

	int PixelsPerByte = 8/BPP;	//used only if BPP are less than 8
	int BitMask = (1<<BPP)-1;	//used only if BPP are less than 8

	// Raster Data Rows are 32bit aligned in BMP files.
	int RowAlignmentInFile = ((4- ((Width*BPP+7)/8)%4)%4); // (bytes)

	for (int row=0; row<Height; row++)
	{
		char * pPixel;
		// If height is positive the bmp is bottom-up, set adequate row info:
		pPixel= Raster + BytesPerRow *
			( (bmih.biHeight>0)? Height-row-1 : row );

		if (BPP >= 8)	// 8 or more BPP: Read as block.
			bmpfile.read (pPixel, Width*BPP/8);

		else				// Less than 8BPP: Read and store byte aligned.
		{
			int charGot;
			for (int col=0; col < Width; col+=PixelsPerByte)
			{
				charGot=bmpfile.get();
				for (int bit=8 ; bit >0 ; bit -= BPP)	// high to low
					*pPixel++ = (charGot>> (bit - BPP)) & BitMask;
			}
		}
		// Ignore aligment bytes of file:
		for (int m=0; m<RowAlignmentInFile; m++) bmpfile.get ();
	}

	bmpfile.close();
	return 1;
}