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

来源:互联网 发布:淘宝gxg官方店和旗舰店 编辑:程序博客网 时间:2024/05/18 23:28
利用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;}// 获取图像元数据构造GlImageGdiplus::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];elseglImageData[CUR_POS * 4 + destA] = 255;}}}pBitmap->UnlockBits (&bitmapData);delete pBitmap;// 结束GDI+Gdiplus::GdiplusShutdown (gdipToken);return glImageData;}

原创粉丝点击