超大图象的移动(300分)

  • 主题发起人 主题发起人 tempc
  • 开始时间 开始时间
T

tempc

Unregistered / Unconfirmed
GUEST, unregistred user!
我正在做一个简单的浏览器,需要实现图像的缩放和平滑移动(像ACDSEE那样)。
现在碰到一个问题,在浏览一副480 X 480的图象时,如果用户不断点击放大按钮,则图象
的尺寸可能变得很大,如4096 X 4096。这时,如果我创建一个4096 X 4096大小的DDB,保存
放大了的图象,那么会占用很大内存,而且DDB的大小超过了一定返回后就无法显示了;但是
如果我在用户每移动一次图象时,调用StretchDraw将图象实时地画到Canvas上,那么在实际
显示时有明显的停滞感,无法做到平滑移动。请问大家有什么好的解决方法。
 
大图象的显示,不要将整幅图象放上去,保留一份备份,仅仅画上显示在屏幕区域的部分就可以了。
 
用一个IMAGE就行了啊。装进去后原来大小,小的就置中,大的就靠左上,
放大缩小很好控制,移动只要移控件就行了。
 
to 卷起千堆雪tyn:
是什么形式的备份?

to kkyy:
IMAGE控件处理很大的图象时,照样会有问题。而且移动的时候会有闪烁。
 
nibble:就是将图象放在内存里,但是显示的时候仅仅显示屏幕区域那么大小就是了,不用将整幅图象放上去。
比如说你的图象4000×4000,屏幕区域800×600,那么你在移动时想显示的是原图象(2000,1500)这个起始坐标
到(2800,2100)这个终止坐标的图象,那么你就BitBlt(....,0,0,800,600,....2000,1500,。。。);
也不知有没有说明白。
 
to 卷起千堆雪tyn:
我现在基本就是这么做的,但是如果图象放大到4096 x 4096, 那么放在内存中的图象
就要占用很多的内存,而且Windows中DDB图象的大小是有一定限制的,超过它就会出错了。
 
你的设计思想不对。用户看到的是视图而不是数据,所以你应在内存中保留一份数据,在
窗口显示用户想看到的部分,总的资源因该是数据所占内存+视图显示所占内存+缓冲区大小
。缓冲区用于准备视图,如下如果视口正在显示5,可以利用线程将12346789准备在内存中
同样放大缩小也可以预先准备。除非你开发数据库的东西,不要老想着用控件,会毁了你自
己的。
1 2 3
4 5 6
7 8 9
 
to Crane:
如你所说,当前显示的是视图5,但是我不知道用户下一步会向哪个方向移动,所以,
我还是需要将12346789的数据准备为内存中的图象(只是尚未显示出来而已),否则如果
到用户移到一块新的区域中,再将数据临时转换为视图,则必然会有一个停滞。综上,在
内存中还是需要准备整幅图象,占用大量内存的?
 
在图象处理中现在都倾向于偏重于存储空间的小和数据显示酸法的高效
所以你还是要只保留一个数据备分,而把精力放在如何高速显示某部分到某个指定区域
如果按你的做法,你的程序一定会容易撑死。
 
to onedot:
但是我的数据是原始的480 X 480的图象,而要将其中的一部分放大后显示到某指定区域,
只能使用StretchDraw或者StretchBlt,二者的效率都不是我能控制的。
 
不一定正确:
procedure TForm1.FormCreate(Sender: TObject);
begin
form1.DoubleBuffered:=true;
end;
 
to ldaan3:
DoubleBuffered只能消除闪烁,无法提升数据-》视图的显示速度。
 
StretchBlt效率同BitBlt,且只有这两个函数效率最高。
 
你的email,发给你一个例子
 
还有一种方法,你可以试试做隔行扫描。或交错扫描,这样起码可以为你减少一半的内存消耗。
 
关于放大,与移动
我是这样做的,,

我没有放大原图,因为如你所说,占内存,,
我只保存了原图作备份,
然后根据放大率,算出在原图中的,
然后把这区域copy下来,并放大到Image的大小就可以了。。

我已经实现了这样的功能,你可以试试,速度很快。
有事,Litangel@zkpacs.com.cn
 
至于移动
可用两个变量来或一个TPoint记录,放大后把偏移的位移加上就可以了。。
 
还是朋友:
我也想这样做,但总觉得无法精确定位,能不能给小弟发一份源代码
mycybyby@163.com
 
还是朋友:
俺也想要,先谢谢了!
ydystory@vip.sina.com
 
我最近做了一个,象游戏星际争霸中地图的效果,大图大移动当然没问题了
 
后退
顶部