我有一些使用具有Alpha通道的CImage的现有代码,并且需要旋转它。

我发现了以下建议,该建议将CImage转换为GDI +位图,然后对其进行旋转,旋转后的结果最终返回到CImage中。

Bitmap* gdiPlusBitmap=Bitmap::FromHBITMAP(atlBitmap.Detach());
gdiPlusBitmap->RotateFlip(Rotate90FlipNone);
HBITMAP hbmp;
gdiPlusBitmap->GetHBITMAP(Color::White, &hbmp);
atlBitmap.Attach(hbmp);

显然,它无需实际复制位图字节就可以工作,这很棒,但是问题是,如果从HBITMAP创建位图对象,则会丢弃alpha通道。

显然,要保留Alpha通道,您必须改为使用构造函数创建位图
Bitmap(
  [in]  INT width,
  [in]  INT height,
  [in]  INT stride,
  [in]  PixelFormat format,
  [in]  BYTE *scan0
);

因此,我试图改写上面的内容以使用此构造函数,但是CImage和Bitmap之间的交互有点困惑。我想我需要像这样创建位图
Bitmap* gdiPlusBitmap = new Bitmap(
            pCImage->GetWidth(),
            pCImage->GetHeight(),
            pCImage->GetPitch(),
            PixelFormat32bppARGB,
            (BYTE *)pCImage->GetBits());
nGDIStatus = gdiPlusBitmap->RotateFlip(Rotate90FlipNone);

但我不确定如何使CImage接受更改(以便最终使原始CImage旋转),或在何处删除Bitmap对象。

有人知道保留alpha通道的正确方法吗?

理想情况下,我希望避免复制位图数据,但这不是强制性的。

最佳答案

您可以使用Gdiplus::GraphicsCImage上绘制位图。

请注意,如果图片不支持Alpha通道,则对PixelFormat32bppARGB进行硬编码可能会导致问题。我添加了一些基本的错误检查。

CImage image;
if (S_OK != image.Load(L"c:\\test\\test.png"))
{
    AfxMessageBox(L"can't open");
    return 0;
}

int bpp = image.GetBPP();

//get pixel format:
HBITMAP hbmp = image.Detach();
Gdiplus::Bitmap* bmpTemp = Gdiplus::Bitmap::FromHBITMAP(hbmp, 0);
Gdiplus::PixelFormat pixel_format = bmpTemp->GetPixelFormat();
if (bpp == 32)
    pixel_format = PixelFormat32bppARGB;
image.Attach(hbmp);

//rotate:
Gdiplus::Bitmap bmp(image.GetWidth(), image.GetHeight(), image.GetPitch(), pixel_format, static_cast<BYTE*>(image.GetBits()));
bmp.RotateFlip(Gdiplus::Rotate90FlipNone);

//convert back to image:
image.Destroy();
if (image.Create(bmp.GetWidth(), bmp.GetHeight(), 32, CImage::createAlphaChannel))
{
    Gdiplus::Bitmap dst(image.GetWidth(), image.GetHeight(), image.GetPitch(), PixelFormat32bppARGB, static_cast<BYTE*>(image.GetBits()));
    Gdiplus::Graphics graphics(&dst);
    graphics.DrawImage(&bmp, 0, 0);
}

关于c++ - 旋转CImage并保留其alpha/透明度 channel ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31698641/

10-11 19:04