如何判断TImageList中两幅位图是相同的?(50分)

  • 主题发起人 主题发起人 Wysywyg
  • 开始时间 开始时间
W

Wysywyg

Unregistered / Unconfirmed
GUEST, unregistred user!
我在一个TimageList中Add很多位图,其中重复的非常多,这样也许对资源
造成浪费,所以我想先判断同样的位图是否已存在了.该怎么办呢?
 
不好办!
这样,你要求什么相同?
文件名?长度?

如果是图象相同,真没法子!
一个一个象素比较?不会吧!...
 
可以比较这两副BMP的二进制文件内容,转换二进制有现成的工具。
 
你可用如下方法将imagelist存入stream中:

var bit:TBitmap;
mystream:TMemoryStream;
begin
bit:=TBitmap.Create;
bit.Handle:=ImageList1.GetImageBitmap;
mystream:=TMemoryStream.Create;
bit.SaveToStream(mystream);

用seek和read方法读出每个图标在流中的数据再比较,你需要了解imagelist的存储
方式,32*32与16*16图标的存储方式不太一样,你自己研究研究吧。
 
保存到两个TStringStream中, 然后用comparestr比较两个TStringStream的DataString
是否一样:
var
bit1, bit2: TBitmap;
st1, st2: TStringStream;
i, j : Integer;
begin
st1 := tStringstream.create('');
st2 := tStringstream.create('');
for i := 0 to ImageList1.count-2 do
begin
getbitmap(i, bit1);
getbitmap(i+1, bit2);
bit1.savetostream(st1);
bit2.savetostream(st2);
j := comparestr(st1.datastring, st2.datastring);
// =0: same
....
end;
st1.free;
st2.free;
end;
 
单纯的文件比较可能不能实现所要求的功能.
比如说,一个图象是另一个图象扩大了一圈生
成的,而扩大的部分用背景色填充.你能说这
两个图象不同吗?
 
lhz说的这种情况可以比较.
比较两幅bitmap的scanline. :)
或者生成两个region, 比较两个region啦.
 
>比较两幅bitmap的scanline. :)
从哪条Scanline开始比较啊?每条scanline从哪个象素开始比较啊?
>或者生成两个region, 比较两个region啦.
两个reigon的坐标是什么啊?
 
进行图的比较难度比较大,这不仅是编几条语句就能实现的!除非1=1(和原图比较)
这里牵扯到模糊的概念、似然度等模糊原理的概念。解决的办法:
1、取第一幅图形,进行图形/象的提取;
2、设立一阀值以确定相似度;
3、取第二幅图形,进行图形/象的提取;
if 似然度近似于1 则两幅图形/象相似 否则不相似。
 
我就是这个意思吗!
太难了!两副图相差一个相素难道就不等了吗?

Jams说的挺难实现的!对了,想起来了,有
个研究生课题就是关于这个的,好象是CAD图纸
扫描后的图象净化处理!

可能类似吧!?
 
to lhz: 用getregiondata取得region中第一个rect的(top,left),
然后用offsetrgn把region移到(0,0)开始, 不就能比较了吗?
 
CAD图纸图纸识别的是线,而不是图像,二者的算法也不相同!
 
>用getregiondata取得region中第一个rect的(top,left),
>然后用offsetrgn把region移到(0,0)开始, 不就能比较了吗?
看来你还没明白我的意思,或者你没明白这个问题真正的难点.
 
我明白你的意思, 你明白我的意思了吗?
首先, 取要比较的两幅图象到两个TBitmap中,
第二步: 把左下角像素的颜色做为透明色, 分别生成两个region, (这个不难, 通过scanline
判断颜色是否透明色, 不是的话用createrectrgn, combinergn把它包含到region中, 偷懒
的话甚至可以create一个(x,y,x+1,y+1)大小的rect, 然后包含到region中!)
第三步: 通过GetRegionData可以取到region的信息, 其中包含一个rect(正好容纳整个region的rect),
也就知道这个region离坐标(0,0)的距离, 用OffsetRgn分别移动两个region到坐标(0,0)位置,
第四步: 简单的话可以用EqualRgn判断两个region是否相同(可以省略第三步?),
复杂点, 还是通过GetRegionData分别取得两个Region的全部信息, 其中包含所有构成这个
region的rect, 分别比较这些rect的坐标, 可以设置一个精度, 决定坐标和大小相差多少之内
的rect可以认为是相等的.
这样就可以判断一定大小精度内两幅图象是否相同了. 如果要连颜色一起判断的话就用scanline,
原理相同: 先移位, 再判断.

比较烦琐而已, 说不上难度.
 
首先感谢Another_eYes的热心,但是,不得不声明,您的方法仍然没有效果:
>把左下角像素的颜色做为透明色
如果这么简单的准则就能够将图象的背景与前景分离,那么世界上那么多研究
图象处理的人都可以跳楼了(我也是其中一员,见笑了//haha).我们用了各种
方法分离前景和背景,效果都很不理想.且不说具有复杂结构的背景,单是简单
的单色背景,如果是由摄像机/采集卡取得,由于噪声的影响,并不存在单一颜色
的区域.在前景背景交界的地方,边界变得模糊,导致不可能准确定位.于是,两
幅图象中取得的前景区域形状/大小/位置都不一样.位置的差异可以用您的方
法消除,但形状和大小怎么办?

另外就是采样精度的问题.由于图象的采样精度比较低(相对于其它媒体),所以
量化噪声比较大,这更导致问题的复杂化.比如,错位半个象素采样,可能得到很
不相同的两幅图象,虽然人看起来都是一样的.

如果还有尺度变化,问题就更复杂了.
 
就事论事, 现在讨论的不是比较两幅扫描得到的图象是否相同, 只是要比较TImageList中是否
有重复加载的图片. 所以不必考虑那么多, 用字符串比较就完全能达到目的了.
 
多人接受答案了。
 
后退
顶部