// 显示图像。参数:设备句柄,x坐标,y坐标,图像数据,不透明度(0 - 1)
VOID ImageDraw(HDC DC, INT x, INT y, CONST BitmapData *data, float alpha = 1.0f)
{
BITMAPINFO bi;
RECT r, r2;
LPVOID scan0;
BitmapData dst, src;
// 获取DC可见矩形
if (GetClipBox(DC, &r) <= NULLREGION) return;
r.left = r.top = 0;
r2.left = x;
r2.top = y;
r2.right = data->Width + x;
r2.bottom = data->Height + y;
// 计算data与DC的交集到r,同时获取实际显示的子图像数据src
if (!IntersectRect(&r, &r, &r2)) return;
GetBitmapData(data, x < 0? -x : 0, y < 0? -y : 0,
r.right - r.left, r.bottom - r.top, &src);
// 按src尺寸建立新的32位图像数据dst
dst.Width = src.Width;
dst.Height = src.Height;
dst.Stride = dst.Width << 2;
dst.Scan0 = scan0 = (LPVOID)new CHAR[dst.Height * dst.Stride];
dst.Reserved = 0;
GetBitmapInfoHeader(&src, &bi);
// 如果alpha<1,或者data含Alpha信息,获取DC可见区域图像到dst
if (alpha < 1.0f || HasAlphaFlag(data))
GetDCImageData(DC, r.left, r.top, &dst, &bi);
// dst扫描线内存转换成Windows位图格式
dst.Scan0 = (LPBYTE)scan0 + (dst.Height - 1) * dst.Stride;
dst.Stride = -dst.Stride;
// 图像混合
ImageMixer(&dst, &src, alpha);
// 还原dst扫描线内存格式后,传输到DC
dst.Scan0 = scan0;
BitBltImageData(DC, r.left, r.top, &dst, &bi);
delete[] scan0;
}
//---------------------------------------------------------------------------

  从上面代码看,图像显示是Windows API和《C++图像处理 -- 图像合成》几个图像合成函数的组合。
  下面用《C++图像处理 -- 图像合成》中的例子,将其中的GDI+显示方法改为本文的ImageDraw函数:

 

void __fastcall TForm1::Button1Click(TObject *Sender)
{
Gdiplus::Bitmap *dest =  new Gdiplus::Bitmap(L"..\..\media\xmas_011.png");
Gdiplus::Bitmap *source =  new Gdiplus::Bitmap(L"..\..\media\Apple.png");
//  Gdiplus::Graphics *g = new Gdiplus::Graphics(Canvas->Handle);
//  g->DrawImage(dest, 0, 0);
//  g->DrawImage(source, dest->GetWidth(), 0);
BitmapData dst, src;
LockBitmap(dest, &dst);
LockBitmap(source, &src);
ImageDraw(Canvas->Handle, 0, 0, &dst, 1);            //
ImageDraw(Canvas->Handle, dst.Width, 0, &src, 1);    //
ImageMixer(&dst, &src, 0.75);
ImageDraw(Canvas->Handle, dst.Width << 1, 0, &dst, 1);//
UnlockBitmap(source, &src);
UnlockBitmap(dest, &dst);
//  g->DrawImage(dest, dest->GetWidth() << 1, 0);
//  delete g;
delete source;
delete dest;
}
//---------------------------------------------------------------------------

  运行效果与《C++图像处理 -- 图像合成》例子效果是一样的,截图如下: