windows下利用gdi+读取图片并转换成opengl纹理支持的像素格式

利用windows自带的gdi+库,可以很方便地读取一般格式的图片,例如bmp,jpg和png。下面这段代码作为opengl贴纹理的第一步,首先读取图片其次转换成opengl支持的像素格式(从ARGB或RGB转换成RGBA)。可惜gdi+不支持tga,所以对于这种格式的图片,还得另外写代码去处理。
#include <Windows.h>
#include <GdiPlus.h>

#pragma comment (lib, "gdiplus.lib")

#define CUR_LINE ((bitmapHeight - 1 - y) * stride)
#define CUR_POS (y * bitmapWidth + x)


unsigned char * loadNormalFormat (const wstring & path)
{
	// 启动GDI+
	Gdiplus::GdiplusStartupInput gdipSIn;
	unsigned long gdipToken;
	Gdiplus::GdiplusStartup (&gdipToken, &gdipSIn, NULL);

	// 加载图像文件
	Gdiplus::Bitmap * pBitmap = new Gdiplus::Bitmap (path.c_str ());

	// 获得图像高宽
	unsigned int bitmapWidth = pBitmap->GetWidth ();
	unsigned int bitmapHeight = pBitmap->GetHeight ();
	if (bitmapWidth <= 0 || bitmapHeight <= 0) {
		delete pBitmap;
		// 结束GDI+
		Gdiplus::GdiplusShutdown (gdipToken);
		return NULL;
	}

	// 获取图像元数据构造GlImage
	Gdiplus::Rect bitmapArea (0, 0, bitmapWidth, bitmapHeight);
	Gdiplus::BitmapData bitmapData;
	pBitmap->LockBits (&bitmapArea, Gdiplus::ImageLockModeRead,
		pBitmap->GetPixelFormat (), &bitmapData);

	const BYTE * imageData = (BYTE *)bitmapData.Scan0;
	int stride = bitmapData.Stride;
	unsigned char * glImageData = NULL;
	if (imageData != 0) {
		unsigned char * glImageData =
				new unsigned char[bitmapWidth * bitmapHeight * 4];
		const int destR = 0, destG = 1, destB = 2, destA = 3;
		int srcR, srcG, srcB, srcA, bytesPerPixel;

		// 根据像素格式设置初始值
		switch (bitmapData.PixelFormat)
		{
		case PixelFormat24bppRGB:
			srcR = 2; srcG = 1; srcB = 0; bytesPerPixel = 3;
			break;
		case PixelFormat32bppARGB:
			srcA = 3; srcR = 2; srcG = 1; srcB = 0; bytesPerPixel = 4;
			break;
		default: // 图片的像素格式不支持
			delete [] glImageData;
			pBitmap->UnlockBits (&bitmapData);
			delete pBitmap;

			// 结束GDI+
			Gdiplus::GdiplusShutdown (gdipToken);
			return NULL;
		}

		// 复制及转换图像数据
		for (unsigned int y = 0; y < bitmapHeight; ++y) {
			for (unsigned int x = 0; x < bitmapWidth; ++x) {
				glImageData[CUR_POS * 4 + destR] = 
					imageData[CUR_LINE + x * bytesPerPixel + srcR];
				glImageData[CUR_POS * 4 + destG] =
					imageData[CUR_LINE + x * bytesPerPixel + srcG];
				glImageData[CUR_POS * 4 + destB] =
					imageData[CUR_LINE + x * bytesPerPixel + srcB];
				if (bytesPerPixel == 4)
					glImageData[CUR_POS * 4 + destA] =
					imageData[CUR_LINE + x * bytesPerPixel + srcA];
				else
					glImageData[CUR_POS * 4 + destA] = 255;
			}
		}
	}

	pBitmap->UnlockBits (&bitmapData);
	delete pBitmap;

	// 结束GDI+
	Gdiplus::GdiplusShutdown (gdipToken);
	return glImageData;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值