求救....图片背景色透明.....

mdejtod 2008-07-10 12:38:04
RT...
解析GIF,得到每一帧后画到一个IMAGEE 上,再将它贴到摄像头上,可是背景无法透明...请问要怎么处理?这一是段GDI+的RGBA 转 ARGB的代码,在这里面可以进行透明,但其它色会丢失..
var a,r,g,b: Byte;
bd: TBitmapData;
hd : PChar;
rc : TRect;
img : PBYTE;
png : TGpBitmap;
Func_GifImage_Draw(Pointer(OverlayGifs.Layers[i].dwHGifImage), OverlayGifs.Layers[i].nIDX,Image1.Canvas.Handle);

// 利用TImage.Picture.Bitmap的图像句柄Handle和调色板属性Palette建立一个GDI+位图
bmp.Assign(image1.Picture.Bitmap);
DrawTrans(Image1.Canvas,320,240,bmp,clred);
with Image1.Picture.Bitmap do
Png := TGpBitmap.Create(Handle,Palette);
if (png <> nil) and (png.Width > 0) then
begin
rc.X := 0; rc.Y := 0;
rc.Width := png.Width;
rc.Height := png.Height;
bd := png.LockBits(rc,[imRead], pf32bppARGB);
img := PBYTE(bd.Scan0);
for j := 0 to bd.Height -1 do
begin
hd := pchar(img) + j * bd.Stride;
for k := 0 to bd.Width -1 do
begin
r := byte(hd[k*4+0]);
g := byte(hd[k*4+1]);
b := byte(hd[k*4+2]);
a := byte(hd[k*4+3]);

{hd[k*4+0] := char(a);
hd[k*4+1] := char(r);
hd[k*4+2] := char(g);
hd[k*4+3] := char(b); } //动画正常显示,背景不透明,(黑色,白,蓝)

hd[k*4+3] := char(a);
hd[k*4+1] := char(r);
hd[k*4+2] := char(g);
hd[k*4+0] := char(b);
hd[k*4+3] := char(b); //背景可以透明,但是B色丢失(显示很淡)
end;
end;
m_pConfig.AddOverlay((TArrByte(bd.Scan0))[0], png.Width, png.Height, 0, 0, i);
png.UnlockBits(bd);
end;

请问可不可以在循环中进行处理?将它透明化然后再贴到摄像头上?万分感谢
...全文
1727 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿发伯 2008-07-12
  • 打赏
  • 举报
回复
上面例子中Timer1.Interval 设置为100 - 200,自己调整
阿发伯 2008-07-12
  • 打赏
  • 举报
回复
终于想办法把背景替换成带透明度的了,下面是用你给的图片制作的动画演示程序。也许你觉得颜色还是有些“淡”,客观上,是光晕部分有些损失,主观上,由于去掉黑色背景后,对比不强烈引起的视觉效果,供参考吧。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Gdiplus, ActiveX, ExtCtrls;

type
TForm1 = class(TForm)
Timer1: TTimer;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
Index: Integer;
Count: Integer;
Images: array of TGpImage;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Math;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
type
TARGBRect = packed record
Blue, Green, Red, Alpha: Byte;
end;
var
I, x, y: Integer;
W, H: Integer;
Image: TGpImage;
bkImage: TGpImage;
bmp: TGpBitmap;
bg: TGpGraphics;
GUID: TGUID;
ig: TGpGraphics;
Data: TBitmapData;
P: PInteger;
begin
DoubleBuffered := True;
// 打开图像文件
Image := TGpImage.Create('e:\0.gif');
W := Image.Width;
H := Image.Height;
BkImage := TGpImage.Create('e:\1.gif');
bmp := TGpBitmap.Create(W, H, pf32bppARGB);
bg := TGpGraphics.Create(bmp);
try
Image.GetFrameDimensionsList(@GUID, 1);
// 获取图像祯数
Count := Image.GetFrameCount(GUID);
SetLength(Images, Count);
for I := 0 to Count - 1 do
begin
Image.SelectActiveFrame(GUID, I);
bg.DrawImage(Image, 0, 0, W, H);
Data := bmp.LockBits(GpRect(0, 0, W, H), [imRead, imWrite], pf32bppARGB);
P := Data.Scan0;
for y := 1 to Data.Height do
for x := 1 to Data.Width do
begin
// 计算不透明度,三种方法都试了
with TARGBRect(P^) do
Alpha := Max(Red, Max(Green, Blue));
//Alpha := (Red + Green + Blue) div 3;
//Alpha := (306 * Red + 601 * Green + 117 * Blue) div 1024;
Inc(P);
end;
// 如果演示效果行,可以把Data.Scan0传递给你的那个函数m_pConfig.AddOverlay
bmp.UnlockBits(Data);
Images[I] := TGpBitmap.Create(W, H, pf32bppARGB);
ig := TGpGraphics.Create(Images[I]);
ig.DrawImage(BkImage, 0, 0, W, H);
ig.DrawImage(bmp, 0, 0, W, H);
ig.Free;
end;
finally
bg.Free;
bmp.Free;
BkImage.Free;
Image.Free;
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
I: Integer;
begin
for I := 0 to Count - 1 do
Images[I].Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
g: TGpGraphics;
begin
g := TGpGraphics.Create(Canvas.Handle);
try
g.DrawImage(Images[Index], 0, 0);
finally
g.Free;
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Inc(Index);
if Index = Count then
Index := 0;
Invalidate;
end;

end.
mdejtod 2008-07-12
  • 打赏
  • 举报
回复
嗯 ..再次谢谢你..
我原本也是在循环中对RGB色进行变换了,就是太淡了.效果不怎么好
暂时只能先这样了
mdejtod 2008-07-11
  • 打赏
  • 举报
回复
mdejtod 2008-07-11
  • 打赏
  • 举报
回复
这破CSDN,怎么图片显示不了
http://tg1a161.mail.163.com/netfolder/servlet/nfapp/GetFile?sid=jDjqdkPPEaMKjiuEWgPPqldYmAQqtOYP&mid=1tbinxMtMEL+9dj6OQAAsD

往IMAGE 或BMP ...上放这张图片时,怎么让它透明化?
mdejtod 2008-07-11
  • 打赏
  • 举报
回复
再格式转化一次不太现实...这个是实时往摄像头上贴动画的...要考虑性能和时间..
无条件为你 2008-07-11
  • 打赏
  • 举报
回复
可以考虑借助PNG格式,此格式可以保证透明。
jacknes009 2008-07-11
  • 打赏
  • 举报
回复
恩,,,看看。。不怎么看的懂。。。。
阿发伯 2008-07-11
  • 打赏
  • 举报
回复
对不起,让你失望了。
“黑色”背景很容易搞定(之所以把“黑色”用引号引上,我早就说过,看上去是黑色,其实不只一种颜色,而是由一个范围的颜色值组成的),多测试几下范围就可行了。
关键是你原图的光照效果已经与原“黑色”背景融为一体,形成了混合半影调颜色,我想多牛的人也没有很好的办法,即使用Photoshop魔棒也没法弄干净。
下面是我试验的代码, 你可以修改BkMaxColor,但无论修改多大,半影调也没法重现!

我试验形成的图片01.rar也通过附件发给你看,0-x.png是没有背景的,01-x.png是加了背景的。

const
BkMaxColor = $FF3A3A3A; // 最大背景颜色值
var
I, Count: Integer;
Clsid: TClsid;
Image: TGpImage;
bkImage: TGpImage;
Attr: TGpImageAttributes;
bmp: TGpBitmap;
tmp: TGpBitmap;
tg, bg: TGpGraphics;
GUID: TGUID;
begin
// 打开图像文件
Image := TGpImage.Create('e:\0.gif');
BkImage := TGpImage.Create('e:\1.gif');
tmp := TGpBitmap.Create(Image.Width, Image.Height, pf32bppARGB);
tg := TGpGraphics.Create(tmp);
bmp := TGpBitmap.Create(Image.Width, Image.Height, pf32bppARGB);
bg := TGpGraphics.Create(bmp);
Attr := TGpImageAttributes.Create;
try
// 设置透明色范围
Attr.SetColorKey($FF000000, BkMaxColor);
Image.GetFrameDimensionsList(@GUID, 1);
// 获取图像祯数
Count := Image.GetFrameCount(GUID);
GetEncoderClsid('image/png', Clsid);

for I := 0 to Count - 1 do
begin
// 选择激活祯
Image.SelectActiveFrame(GUID, I);
// 画当前祯到临时图
tg.DrawImage(Image, 0, 0, Image.Width, Image.Height);
// 合成图初始化为透明色
bg.Clear(0);
// 画背景图,如不需要背景图,可将下面注释掉
bg.DrawImage(BkImage, 0, 0, bmp.Width, bmp.Height);
// 画临时图
bg.DrawImage(tmp, GpRect(0, 0, bmp.Width, bmp.Height),
0, 0, tmp.Width, tmp.Height, utPixel, Attr);
// 保存
bmp.Save('e:\01-' + IntToStr(I) + '.png', Clsid);
end;
finally
Attr.Free;
bg.Free;
bmp.Free;
tg.Free;
tmp.Free;
BkImage.Free;
Image.Free;
end;
end;

mdejtod 2008-07-11
  • 打赏
  • 举报
回复
邮件已发,,.谢谢!!!
阿发伯 2008-07-11
  • 打赏
  • 举报
回复
在邮件中把要求说清楚!
阿发伯 2008-07-11
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 mdejtod 的回复:]
将下面这张图片叠到上面那张图片上,可以使下面这张图片透明...即没有黑色背景色...能否实现呢?
[/Quote]
不就是2张图片合成吗?应该不难。我反复问了多次,你总是说“贴”,你把图发到我的邮箱(maozefa@hotmail.com),我看看怎么回事
阿发伯 2008-07-10
  • 打赏
  • 举报
回复
hd[k*4+3] := char(b); //背景可以透明,但是B色丢失(显示很淡)

这是毫无道理的赋值。hd[k*4+3] 是Alpha字节,不明白把Blue字节值b赋给它意义何在?正确的做法应该是首先确定背景色的颜色值,然后逐像素判断替换背景色为0(或者背景色的Alpha=0)。不过GIF图片的背景色看上去是一样的,其实可能不只是一种颜色(抖动后又多个颜色成分),所以,重点在于确定背景色的颜色值有几种。
jmh521 2008-07-10
  • 打赏
  • 举报
回复
沙发...帮不上..帮顶下
mdejtod 2008-07-10
  • 打赏
  • 举报
回复
将下面这张图片叠到上面那张图片上,可以使下面这张图片透明...即没有黑色背景色...能否实现呢?
mdejtod 2008-07-10
  • 打赏
  • 举报
回复
mdejtod 2008-07-10
  • 打赏
  • 举报
回复
mdejtod 2008-07-10
  • 打赏
  • 举报
回复
mdejtod 2008-07-10
  • 打赏
  • 举报
回复
调用 一个 directshow 中的 overlay 接口来贴的..
阿发伯 2008-07-10
  • 打赏
  • 举报
回复
我不明白的就是这句“然后将BMP贴到摄像头上”,怎么贴?
加载更多回复(12)

1,183

社区成员

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

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