屏幕在16位色的情况下,alphablend函数是不是无效?

wang_cai_ok 2007-07-09 03:54:57
我的程序使用alphablend函数将内存中创建的HDC叠加至屏幕时,在屏幕32位色的情况下正常,但当屏幕颜色改为16位色时程序就不显示了,请问是怎么回事,用Bitblt正常,是不是屏幕在16位色的情况下,alphablend函数无效?
...全文
328 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
wang_cai_ok 2007-08-25
  • 打赏
  • 举报
回复
我想问问叠加后的结果输出成jpg图片
wang_cai_ok 2007-07-28
  • 打赏
  • 举报
回复
谢谢superarhow(苏泊尔耗)
superarhow 2007-07-26
  • 打赏
  • 举报
回复
procedure Tform1.W;
var GPGraph: TGPGraphics;
hdcTemp: HDC;
hBMP: HBITMAP;
GPImage: TGPImage;
begin
hdcTemp := CreateDC('DISPLAY', nil, nil, nil);
w_memory := CreateCompatibleDC(hdcTemp);
hBMP := CreateCompatibleBitmap(hdcTemp, Width, Height);
GPImage := TGPImage.Create('w\12.png');
SelectObject(w_memory, hBMP);
GPGraph := TGPGraphics.Create(w_memory);
GPGraph.DrawImage(GPImage, 0, 0, GPImage.GetWidth(), GPImage.GetHeight());
GPImage.Free;
GPGraph.ReleaseHDC(w_memory);
GPGraph.Free;
DeleteObject(hBMP);
ReleaseDC(0, hdcTemp);
DeleteDC(hdcTemp);
end;

这个函数可能有问题, w_memory := CreateCompatibleDC(hdcTemp);要改成w_memory := CreateCompatibleDC(0);否则位图可能选不进去。
可能已经有人说过了,位图能否选进一个DC,是有规则的:
1. 兼容DC只能选兼容位图,即位图格式和DC中的位图格式完全一样;
2. 内存DC可以选入任何设备无关位图;
hBMP := CreateCompatibleBitmap(hdcTemp, Width, Height);
这也有问题,虽然这样创建是兼容了,但是在屏幕是16位色的情况下,你的位图也是16位的了,就没有alpha通道了。应当改成用CreateDIBSection函数来创建。


superarhow 2007-07-25
  • 打赏
  • 举报
回复
有效的,关键是看你创建这个位图用的API,一定要是CreateDIBSection,并且一定要指明32位,不能用CreateCompatibleBitmap或者CreateDIBitmap
brightyang 2007-07-25
  • 打赏
  • 举报
回复
详情请见:http://blog.csdn.net/starofrainnight/archive/2007/03/19/1533617.aspx
16位色AlphaBlend深度探索
brightyang 2007-07-25
  • 打赏
  • 举报
回复
void DrawAlphaBlend_cpp(
  WORD * dstAddr, // 目标图的起始地址
  WORD * srcAddr, // 源图的起始地址
  DWORD cntX, // 横轴要处理的宽度
  DWORD cntY, // 纵轴要处理的高度
  DWORD dstSkipBytes, // 目标地址在处理完横向宽度最后一个点后要跳过多少个字节
  DWORD srcSkipBytes, // 源地址在处理完横向宽度最后一个点后要跳过多少个字节
  DWORD srcAlphaLevel )// Alpha级数 0 ~ 32
{
  DWORD srcColor; // 源点颜色
  DWORD dstColor; // 目标点颜色
  // 此值要根据你所需要处理的像素格式而定,这里仅指 16 位色 555模式 RGB顺序
  DWORD Mask32 = 0x3E07C1F;
  WORD xCnt = cntX; // 暂存宽度值,以便循环运算


  for( ;cntY>0; --cntY, cntX = xCnt )
  {
    for( ; cntX>0; --cntX )
    {
      srcColor = *srcAddr | (*srcAddr<<16); //扩宽到32位
      srcColor &= Mask32; // 通过掩码得到正确的扩宽颜色值
      dstColor = *dstAddr | (*dstAddr<<16);
      dstColor &= Mask32;
      srcColor = (srcColor - dstColor) * srcAlphaLevel / 32 + dstColor;
      srcColor &= Mask32; // 通过掩码把结果的其它无用数据去掉
      // 还原到正确的16位颜色值
      srcColor = (srcColor & 0xffff0000)>>16 | (srcColor & 0x0000ffff );
      
      // 改变目标图的点为结果点,这样直接显示目标图即可知道整个结果
      *dstAddr = srcColor;
      ++dstAddr;
      ++srcAddr;
    }
    dstAddr = (WORD*)((BYTE*)dstAddr + dstSkipBytes);
    srcAddr = (WORD*)((BYTE*)srcAddr + srcSkipBytes);
  }
}

wang_cai_ok 2007-07-25
  • 打赏
  • 举报
回复
to 各位:
下面是我的delphi源码,用alphablend叠加带透明通道的图片,在屏幕色深32bits时正常,在此16位色时不显示,请帮我看看

procedure TForm1.FormCreate(Sender: TObject);
var GPImage: TGPImage;
begin
Self.DoubleBuffered := True;
BorderStyle := bsNone;
m_Blend.BlendOp := AC_SRC_OVER;
m_Blend.BlendFlags := 0;
m_Blend.AlphaFormat := AC_SRC_ALPHA;
m_Blend.SourceConstantAlpha := 255;
GPImage := TGPImage.Create('backend.png');
Width := GPImage.GetWidth;
Height := GPImage.GetHeight;
GPImage.Free;

ptWinPos.X := 20;
ptWinPos.Y := 20;
sizeWindow.cx := Width;
sizeWindow.cy := Height;
ptSrc.x := 0;
ptSrc.y := 0;
W;
ReDraw;
end;

procedure Tform1.W;
var GPGraph: TGPGraphics;
hdcTemp: HDC;
hBMP: HBITMAP;
GPImage: TGPImage;
begin
hdcTemp := CreateDC('DISPLAY', nil, nil, nil);
w_memory := CreateCompatibleDC(hdcTemp);
hBMP := CreateCompatibleBitmap(hdcTemp, Width, Height);
GPImage := TGPImage.Create('w\12.png');
SelectObject(w_memory, hBMP);
GPGraph := TGPGraphics.Create(w_memory);
GPGraph.DrawImage(GPImage, 0, 0, GPImage.GetWidth(), GPImage.GetHeight());
GPImage.Free;
GPGraph.ReleaseHDC(w_memory);
GPGraph.Free;
DeleteObject(hBMP);
ReleaseDC(0, hdcTemp);
DeleteDC(hdcTemp);
end;

procedure Tform1.ReDraw;
var hDC, hdcScreen, m_hdcMemory, hOldHandle: THandle;
hBMP: HBITMAP;
GPGraph: TGPGraphics;
GPImage: TGPImage;
begin
hdc := GetDC(0);
hdcScreen := GetDC(0);
GPImage := TGPImage.Create('backend.png');
m_hdcMemory := CreateCompatibleDC(hDC);
hBMP := CreateCompatibleBitmap(hdc, Width, Height);
hOldHandle := SelectObject(m_hdcMemory, hBMP);
GPGraph := TGPGraphics.Create(m_hdcMemory);
GPGraph.DrawImage(GPImage, 0, 0, GPImage.GetWidth, GPImage.GetHeight);
DeleteObject(hBMP);

try
Windows.AlphaBlend(m_hdcMemory, 0, 0, Width, Height, w_memory, 0, 0, Width, Height, m_Blend);
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);
UpdateLayeredWindow(Handle, hdcScreen, @ptWinPos, @sizeWindow, m_hdcMemory, @ptSrc, 0, @m_Blend, 2);
finally
GPImage.Free;
GPGraph.ReleaseHDC(m_hdcMemory);
GPGraph.Free;
SelectObject(m_hdcMemory, hOldHandle);
ReleaseDC(0, hDC);
ReleaseDC(0, hdcScreen);
DeleteDC(m_hdcMemory);
end;
OldStyle := GetWindowLong(Handle, GWL_EXSTYLE);
end;

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi GAME,图形处理/多媒体
社区管理员
  • GAME,图形处理/多媒体社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧