Skip to content

Commit

Permalink
fix: 修复 RGB32 格式图像读取后预留通道被填充成 0xFF 的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
yixy-only committed Apr 17, 2024
1 parent 008d333 commit 215a604
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 11 deletions.
4 changes: 2 additions & 2 deletions include/ege.h
Original file line number Diff line number Diff line change
Expand Up @@ -824,10 +824,10 @@ class IMAGE;
typedef IMAGE *PIMAGE;
typedef const IMAGE *PCIMAGE;

// `codepage` sholde be `EGE_CODEPAGE_XXX`, default is `EGE_CODEPAGE_ANSI`.
// `codepage` should be `EGE_CODEPAGE_XXX`, default is `EGE_CODEPAGE_ANSI`.
void EGEAPI setcodepage(unsigned int codepage);
unsigned int EGEAPI getcodepage();
// set whether char message of `getkey()` use UTF-16
// set whether char message of `getkey()` use UTF-16
void EGEAPI setunicodecharmessage(bool enable);
bool EGEAPI getunicodecharmessage();
void EGEAPI setinitmode(int mode, int x = CW_USEDEFAULT, int y = CW_USEDEFAULT);
Expand Down
22 changes: 14 additions & 8 deletions src/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,22 +400,28 @@ void getimage_from_IPicture(PIMAGE self, IPicture* pPicture)
pPicture->Render(getHDC(self), 0, 0, lWidthPixels, lHeightPixels, 0, lHeight, lWidth, -lHeight, 0);
}

int getimage_from_bitmap(PIMAGE pimg, Gdiplus::Bitmap& bitmap)
int getimage_from_bitmap(PIMAGE pimg, Gdiplus::Bitmap& bitmap, bool regardRGB32asARGB)
{
Gdiplus::PixelFormat srcPixelFormat = bitmap.GetPixelFormat();

// 将图像尺寸调整至和 bitmap 一致
int width = bitmap.GetWidth();
int height = bitmap.GetHeight();
int width = (int)bitmap.GetWidth();
int height = (int)bitmap.GetHeight();
resize_f(pimg, width, height);

Gdiplus::PixelFormat destPixelFormat = PixelFormat32bppARGB;

// 将 RGB32 格式视为 ARGB,保留其预留通道作为透明通道使用 (若是将 RGB32 转换成 ARGB,alpha 会被填充成 0xFF)
if ((srcPixelFormat == PixelFormat32bppRGB) && regardRGB32asARGB)
destPixelFormat = PixelFormat32bppRGB;

// 设置外部缓冲区属性,指向图像缓冲区首地址
Gdiplus::BitmapData bitmapData;
Gdiplus::BitmapData bitmapData = {0};
bitmapData.Width = width;
bitmapData.Height = height;
bitmapData.Stride = width * sizeof(color_t); // 至下一行像素的偏移量(字节)
bitmapData.PixelFormat = PixelFormat32bppARGB; // 像素颜色格式: 32 位 ARGB
bitmapData.Scan0 = getbuffer(pimg); // 图像首行像素的首地址
bitmapData.Stride = width * (int)sizeof(color_t); // 至下一行像素的偏移量(字节)
bitmapData.PixelFormat = destPixelFormat; // 像素颜色格式: 32 位 ARGB
bitmapData.Scan0 = getbuffer(pimg); // 图像首行像素的首地址

// 读取区域设置为整个图像
Gdiplus::Rect rect = {0, 0, width, height};
Expand All @@ -424,7 +430,7 @@ int getimage_from_bitmap(PIMAGE pimg, Gdiplus::Bitmap& bitmap)
int imageLockMode = Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf;

//读取 Bitmap 图像内容,以 32 位 ARGB 的像素格式写入缓冲区
bitmap.LockBits(&rect, imageLockMode, PixelFormat32bppARGB, &bitmapData);
bitmap.LockBits(&rect, imageLockMode, destPixelFormat, &bitmapData);

// 解除锁定(如果设置了 ImageLockModeWrite 模式,还会将缓冲区内容复制到 Bitmap)
bitmap.UnlockBits(&bitmapData);
Expand Down
2 changes: 1 addition & 1 deletion src/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,6 @@ class IMAGE
friend void getimage_from_png_struct(PIMAGE, void*, void*);
};

int getimage_from_bitmap(PIMAGE pimg, Gdiplus::Bitmap& bitmap);
int getimage_from_bitmap(PIMAGE pimg, Gdiplus::Bitmap& bitmap, bool regardRGB32asARGB = true);

} // namespace ege

0 comments on commit 215a604

Please sign in to comment.