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;请问可不可以在循环中进行处理?将它透明化然后再贴到摄像头上?万分感谢
解析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;请问可不可以在循环中进行处理?将它透明化然后再贴到摄像头上?万分感谢
解决方案 »
- DBGridEh 第一列隐藏,第三列有个BIT型字段(类似CheckBox),那给这个BIT型字段加一个事件?
- 有点难可以加分,数组的某一段要平均分段,快速求数组下标!
- scktsrvr 的相关问题
- 如何把数据库的操作类放到一个单独的单元中?
- 几个pascal的小程序,回者有分
- Delphi 中使用 windows SDK 中的IPHelper 的问题?
- 请问ERP项目可否用Delphi开发?真的一定要Java开发吗?
- 三个pascal问题,看你能回答对几个?正确有分。
- 请问fastreport的使用,以及双击fastreport控件设计后怎么在delphi中调用,急,谢谢
- 十万火急:怎样在delphi中安装speech SDK api,在哪儿下载?
- dup数据怎么穿路由器??
- select ....in select .....解释下什么意思!多谢!!
r := byte(hd[k*4+0]);
g := byte(hd[k*4+1]);
b := byte(hd[k*4+2]);
a := byte(hd[k*4+3]);
if (r = g) and (g = b) then continue;
hd[k*4+0] := char(a);
hd[k*4+1] := char(r);
hd[k*4+2] := char(g);
hd[k*4+3] := char(b);
改用这种方式,就正常了
但是如果贴的是单张背景色为黑色的GIF就不行,显示为白色,如果再贴另一张上去,就正常了...
不知为什么..解析 后的图片是会白色的...
=========================================
我不知道摄像头需要的像素RGB各分量是怎么排列的,但据我所知,GDI+的TGpBitmap与Delphi的TBitmap的像素RGB各分量的排列是一样的,0:Blue; 1:Green; 2:Red,如果是32位ARGB,则:3:Alpha。(不要把TColor中RGB的排列方式与图像像素RGB的排列方式混为一谈)另外请注意,因为LZ的GDI+ Bitmap是从Image1.Picture.Bitmap转换得来的32位ARGB格式图像,其Alpha值都是$FF
另问你一下,已经取得图片的 scan0 和 RGB 色(24位),能否直接将它转为32位的?
一.逐像素判断的速度太慢了..这是一个,还有就是我的背景图是摄像头,不知道怎么去限它的颜色值
二.已经取得图片的 scan0 和 RGB 色(24位),能否直接将它转为32位的?
有的BMP是单色背景色,有的已经是半透明的....
另外,既然你有多祯GIF图像,为什么不试试直接传递该图像?方法是:
每次只是选择当前祯(可参考我的多祯图像分解文章,但不要分解,只是选择当前页就行了),然后用LockBits方法锁定它(图像格式参数不能改变,只能取TGpBitmap打开GIF图像的原始格式,否则出错。),再将scan0传过去试试。
只是我一直没明白LZ“将GIF贴到摄像头上”是什么意思?
是否不断从摄像头采集图像数据,转换成TBitmap或者TGpBitmap,然后把多桢GIF图像逐祯合成到TBitmap或者TGpBitmap,最后将图像再转换为摄像头所需数据?
如果是这样一个过程就好办了,逐祯选择GIF激活祯,将GIF图片直接合成到TBitmap或者TGpBitmap,这时背景的透明色就起作用了,然后转换为摄像头所需数据
我这边做的操作是,在定时器中解开GIF,然后将BMP贴到摄像头上,没有从摄像头采集图像..
http://tg1a161.mail.163.com/netfolder/servlet/nfapp/GetFile?sid=jDjqdkPPEaMKjiuEWgPPqldYmAQqtOYP&mid=1tbinxMtMEL+9dj6OQAAsD往IMAGE 或BMP ...上放这张图片时,怎么让它透明化?
“黑色”背景很容易搞定(之所以把“黑色”用引号引上,我早就说过,看上去是黑色,其实不只一种颜色,而是由一个范围的颜色值组成的),多测试几下范围就可行了。
关键是你原图的光照效果已经与原“黑色”背景融为一体,形成了混合半影调颜色,我想多牛的人也没有很好的办法,即使用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;
unit Unit1;interfaceuses
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;implementationuses 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.
我原本也是在循环中对RGB色进行变换了,就是太淡了.效果不怎么好
暂时只能先这样了