当我使用bitmap :: FromhbitMap函数创建新的GDiplus ::位图时,所得的位图是不透明的 - 原始HBITMAP的部分透明度都无法保留。

有没有办法从 HBITMAP 创建 Gdiplus::Bitmap 来传递 alpha 通道数据?

有帮助吗?

解决方案 2

事实证明,当从 HBITMAP 创建位图时,GDI+ 永远不会引入 Alpha 通道。

答案是:

  • 使用 GetObject 传入 BITMAP 和 HBITMAP,获取输入 HBITMAP 的宽度和高度(如果输入位图是 DIB,则获取像素数据)。
  • 使用 32 位 PARGB 像素格式创建正确大小的位图。
  • 使用 LockBits 来获取新位图的像素数据内存。
  • 如果您从 GetObject 获取像素,请使用 memcpy 复制 ARGB 值。
  • 对新位图调用 UnlockBits。

就我而言,输入 HBITMAP 的格式对于从输入位图像素数据到新位图像素数据进行直接 memcpy 是正确的。

如果您没有从 GetObject 获取输入像素数据,请使用 GetDIBits 获取正确格式的副本。

其他提示

我认为工作的代码比指令更加有用,所以:

#include <GdiPlus.h>
#include <memory>

Gdiplus::Status HBitmapToBitmap( HBITMAP source, Gdiplus::PixelFormat pixel_format, Gdiplus::Bitmap** result_out )
{
  BITMAP source_info = { 0 };
  if( !::GetObject( source, sizeof( source_info ), &source_info ) )
    return Gdiplus::GenericError;

  Gdiplus::Status s;

  std::auto_ptr< Gdiplus::Bitmap > target( new Gdiplus::Bitmap( source_info.bmWidth, source_info.bmHeight, pixel_format ) );
  if( !target.get() )
    return Gdiplus::OutOfMemory;
  if( ( s = target->GetLastStatus() ) != Gdiplus::Ok )
    return s;

  Gdiplus::BitmapData target_info;
  Gdiplus::Rect rect( 0, 0, source_info.bmWidth, source_info.bmHeight );

  s = target->LockBits( &rect, Gdiplus::ImageLockModeWrite, pixel_format, &target_info );
  if( s != Gdiplus::Ok )
    return s;

  if( target_info.Stride != source_info.bmWidthBytes )
    return Gdiplus::InvalidParameter; // pixel_format is wrong!

  CopyMemory( target_info.Scan0, source_info.bmBits, source_info.bmWidthBytes * source_info.bmHeight );

  s = target->UnlockBits( &target_info );
  if( s != Gdiplus::Ok )
    return s;

  *result_out = target.release();

  return Gdiplus::Ok;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top