网页中的图片被选择后变蓝是如何实现的?(100分)

  • 主题发起人 主题发起人 popeye
  • 开始时间 开始时间
P

popeye

Unregistered / Unconfirmed
GUEST, unregistred user!

在网页中如果用鼠标拖动选择一幅图片,图片上就会覆盖一层很
细的蓝色小网格,使整个图片看起来偏蓝.在程序里如何才能对
bitmap实现这种效果?不会是改图像像素的blue颜色吧,那样很慢,
网页中的很快的.
另外,桌面的图标被选中后也会变蓝,和上面是否用的同样的方法?
 
应该是两个图片,当选中时,偷梁换柱成另一个图片了。
 
Grab,你上面所说的是开玩笑吧???popeye说的那种情况是块选中时的情况
window98底层的控制台控制的。可在图片上面一层画出一个带网点的画布,并
且为透明属性,,我觉得应该是这样。。具体我没试过。
 
如淡淡的笑说的那样的话,怎样实现呢?
 
应该是只有IE里才可以吧,用滤镜功能。
你说的那个应该是Alpha过滤器或者mask过滤器。
filter是花哨,但ns不支持
 
O,我看错了,我对网页不熟, 扣我分吧
 
Crab不一定错呀。可能是用两张图片:选中时处理,还原时还需调原图。
在如资源管理器右边的ListView,某些带Image的ListBox,当项目被选中时,
图标上即带兰色(clHighLight)网格。但实现方法在 VCL Source 里找不到。
听~~
 
自己创建一个位图DC
然后在里面填上某种颜色的象素
用异或的方式BitBit上去
应该就可以了

恢复时就再Bitblt一次
 
同意wrench的说法。
 
wrench的方法可以实现变色,但是用蓝色xor一幅图片蓝色会与原图像混合
结果不是蓝色了,我以前试过的.

我的第一种方法是直接在图像上画点,用canvas.pixel[x,y]:=clblue,可以
实现蓝色小网格,但是速度太慢.第二种方法使用scanline,直接对
image.picture.bitmap操作可以使像素变色;但是对动态创建的一个bitmap
使用后在copyrect到另外一个canvas上却没有任何变化.

还有一个api函数setpixel(handle,x,y,color)可以画点,不知速度是否更快
些等我试试..
 
我说某种颜色
自然不是说兰色了

多试几下
把该用的颜色试出来

 
搞定了.

canvas.pixels[i,j]:=clblue当然可以但是太慢;canvas的源码中: property pixels ..read getpixel write setpixel所以就是setpixel.
还是用的scanline.如果单是给image的图像加上网点的话并不复杂:
var
x,y,z : Integer;

BitMap : TBitMap;
P : PByteArray;
begin

y := 0;

x:=0;

z:=0;

while y<=image1.height do

begin

z:=z*(-1)+1;

x:=z;

P := image1.picture.BitMap.ScanLine[y];

while x<image1.width do

begin

P[3*x] := 255; //知道为什么要*3吗?

p[3*x+1]:=0;

p[3*x+2]:=0;

x:=x+2;

end;

y:=y+2;

end;

image1.refresh;
end;

但是我要的是在一个已经在canvas上的图像上加网点.所以要现在程序
中创建一个
bitmap,把canvas的部分图像copyrect到bitmap,然后在
bitmap上加网点.为什么不在那个canvas上直接画点呢?如果直接画只
能用setpixel不能用scanline,慢.
我是在继续修改TImageDBGrid(我从TDBGrid改写的带背景图的DBGrid,
练功场可下载.我改的好辛苦@$#^&amp;$%!觉得好用就朋友们来封信鼓励鼓
励吧.)当某个单元或者行被选中时一原来默认的蓝色背景显示,这样就
遮住了图片背景;于是我想应该可以把网页上的那种效果加进来.

if HighLightCell then
begin
i:=0;
k:=0;
while i<b.bottom do
begin
P := drawBitMap.ScanLine;
k:=k*(-1)+1;
j:=k;
while j<drawbitmap.width do
begin
P[3*j] := 255;
p[3*j+1]:=0;
p[3*j+2]:=0;
j:=j+2;
end;
i:=i+2;
end;
end;

SetBkMode(Handle, TRANSPARENT);
DrawText(Handle, PChar(Text), Length(Text), R, AlignFlags[Alignment]);

这段代码运行时网点显示不出来.我又加了一个临时的Abitmap中转一下,
给Abitmap加上网点在赋给drawbitmap.网点能显示出来了,但是第一个
显示不出来,第二个以后可以;网点宽度不够也不是要的蓝色.仔细看了
TBitmap的help,发现了Dormant方法.改成:

if HighLightCell then
begin
drawbitmap.Dormant;
i:=0;
k:=0;
while i<b.bottom do
begin
P := drawBitMap.ScanLine;
k:=k*(-1)+1;
j:=k;
while j<drawbitmap.width do
begin
P[4*j] := 255;
p[4*j+1]:=0;
p[4*j+2]:=0;
j:=j+2;
end;
i:=i+2;
end;
drawbitmap.Dormant;
end;

SetBkMode(Handle, TRANSPARENT);
DrawText(Handle, PChar(Text), Length(Text), R, AlignFlags[Alignment]);

这样就一切正常,实现预想的功能了.为什么改成
P[4*j] := 255;
p[4*j+1]:=0;
p[4*j+2]:=0;
宽度就够了颜色也是蓝色了,而在前面那段给image加网点的程序中
P[3*j] := 255;
p[3*j+1]:=0;
p[3*j+2]:=0;
正常,放到这里却不行了呢?scanline返回的pbytearray的每三个字节
代表一个像素的blue,green,red值,4是怎么回事?

哪位大虾明白请赐教!

效果怎样?<img src="http://h_dh.163.net/demo.jpg">
 
小于号被吃掉了,重贴一次

canvas.pixels[i,j]:=clblue当然可以但是太慢;canvas的源码中:
property pixels ..read getpixel write setpixel所以就是setpixel.
还是用的scanline.如果单是给image的图像加上网点的话并不复杂:
var
x,y,z : Integer;
BitMap : TBitMap;
P : PByteArray;
begin
y := 0;
x:=0;
z:=0;
while y lessthan image1.height do
begin
z:=z*(-1)+1;
x:=z;
P := image1.picture.BitMap.ScanLine[y];
while x lessthan image1.width do
begin
P[3*x] := 255; //知道为什么要*3吗?
p[3*x+1]:=0;
p[3*x+2]:=0;
x:=x+2;
end;
y:=y+2;
end;
image1.refresh;
end;

但是我要的是在一个已经在canvas上的图像上加网点.所以要现在程序
中创建一个bitmap,把canvas的部分图像copyrect到bitmap,然后在
bitmap上加网点.如果直接画只能用setpixel不能用scanline,慢.

我是在继续修改TImageDBGrid(我从TDBGrid改写的带背景图的DBGrid,
练功场可下载.我改的好辛苦@$#^&amp;$%!觉得好用就朋友们来封信鼓励鼓
励吧.)当某个单元或者行被选中时一原来默认的蓝色背景显示,这样就
遮住了图片背景;于是我想应该可以把网页上的那种效果加进来.

if HighLightCell then
begin
i:=0;
k:=0;
while i lessthan b.bottom do
begin
P := drawBitMap.ScanLine;
k:=k*(-1)+1;
j:=k;
while j lessthan drawbitmap.width do
begin
P[3*j] := 255;
p[3*j+1]:=0;
p[3*j+2]:=0;
j:=j+2;
end;
i:=i+2;
end;
end;

SetBkMode(Handle, TRANSPARENT);
DrawText(Handle, PChar(Text), Length(Text), R,
AlignFlags[Alignment]);

这段代码运行时网点显示不出来.我又加了一个临时的Abitmap中转一下,
给Abitmap加上网点在赋给drawbitmap.网点能显示出来了,但是第一个
显示不出来,第二个以后可以;网点宽度不够也不是要的蓝色.仔细看了
TBitmap的help,发现了Dormant方法.改成:

if HighLightCell then
begin
drawbitmap.Dormant;
i:=0;
k:=0;
while i lessthan b.bottom do
begin
P := drawBitMap.ScanLine;
k:=k*(-1)+1;
j:=k;
while j lessthan drawbitmap.width do
begin
P[4*j] := 255;
p[4*j+1]:=0;
p[4*j+2]:=0;
j:=j+2;
end;
i:=i+2;
end;
drawbitmap.Dormant;
end;

SetBkMode(Handle, TRANSPARENT);
DrawText(Handle, PChar(Text), Length(Text), R,
AlignFlags[Alignment]);

这样就一切正常,实现预想的功能了.为什么改成
P[4*j] := 255;
p[4*j+1]:=0;
p[4*j+2]:=0;
宽度就够了颜色也是蓝色了,而在前面那段给image加网点的程序中
P[3*j] := 255;
p[3*j+1]:=0;
p[3*j+2]:=0;
正常,放到这里却不行了呢?scanline返回的pbytearray的每三个字节
代表一个像素的blue,green,red值,4是怎么回事?

哪位大虾明白请赐教!

<img src="http://h_dh.163.net/demo.jpg">
 
将调色板的颜色改改不久行了。http://www.csdn.net/delphi下有例子
 
咦?你的 DBGrid 后面怎么可以有一个图像?难道 DBGrid 可以设为透明的吗?
 
没这么麻烦吧?

泥巴图片先装到一个imagelist里面,然后设置
imagelist1.drawingStyle:=dsSelect
imagelist1.BlendColor:=clHighlight

然后
imagelist1.draw(canvas,0,0,1);
就可以了
 
chenlili: 调色板只对256色图像有效

Crab: 练功场可以下载

cAkk:我原以为imagelist只不过是管理图标的小玩艺,没想到还有这个功能,
我试过了确实可行.这种方法更简单,不用多费脑筋;虽然效果看起来
更专业一些,缺点是要在dbgrid里加入一个imagelist动态添加bitmap.
不利于减肥.

 
imagelist并不是仅仅用来装一串图片的,很多控件都用imagelist
来实现类似得很多功能.

BTW: 加一个imagelist并不会增加多少尺寸,因为那只是一个接口文件,
实质是调用的windows自己的DLL.
 
这在flash中很容易解决,就是一个按钮的制作嘛.它的up区是一个图,down是一个图.
这就行了,需要的话我发给你一个例子好了
 
多谢cAkk,又学到了一招.我怎样才能向你一样博学呢,从这个问题可以看出我的知识面窄一些.
 
后退
顶部