建议你不要一点一点读, 可以一行一行读就快多了;Provides indexed access to each line of pixels. __property void * TBitmap::ScanLine[int Row] = {read=GetScanline}; Description ScanLine is used only with DIBs (Device Independent Bitmaps) for image editing tools that do low-level pixel work.
什么是同步模式???我的问题用一个简单的例子来说明: procedure ConvertThread.Execute; var i,j:integer; begin for j:=0 to Form1.Image1.Height do begin for i:=0 to Form1.Image1.Width do begin form1.Image2.Canvas.Pixels[i,j]:=form1.Image1.Canvas.Pixels[i,j]; end; end; end; 这是一个线程的execute中的内容,请各位试试,我运行的时候确实是有些点被绘成白色的空值了, 如果要设成同步模式,那该怎么设呢??对不起,我只有这点分了,请帮帮忙吧
正如楼上几位所说,因为性能的原因,VCL不直接支持线程,或者说是线程不安全的。 但是,可以用TThread.Synchronize来同步线程对VCL的操作。 请看下面的例子,具体请看Delphi中TThread的帮助。This example shows how to call a button抯 click method in a thread-safe manner:procedure TMyThread.PushTheButton;begin Button1.Click(); end;procedure TMyThread.Execute; begin ... Synchronize(PushTheButton); ... end;所以,比照这个例子,你应该把画图函数独立成一个过程,然后在ConvertThread.Execute中通过Synchronize来调用。 还有,提示一下,如果你一点点甚至是一条条画图的话,速度是很慢的。建议在内存中开辟一个bitmap,画上去,然后整个复制到界面上。这样快非常之多!
procedure ConvertThread.Execute; var i,j:integer; begin for j:=0 to Form1.Image1.Height do begin for i:=0 to Form1.Image1.Width do begin Synchronize(drawBitmap); end; end; end; procedure TMyThread.drawBitmap();begin form1.Image2.Canvas.Pixels[i,j]:=form1.Image1.Canvas.Pixels[i,j]; end;
真不好意思。。又遇到问题了。。Synchronize的参数好想必须是不带参数的函数,如果我写成:procedure mythread.Execute; var i,j:integer; begin for j:=0 to Form1.Image1.Height do begin for i:=0 to Form1.Image1.Width do begin Synchronize(drawBitmap(i,j));//这里会出错!!!!!!!!!! end; end; end;procedure mythread.drawBitmap(x,y:integer); begin form1.Image2.Canvas.Pixels[x,y]:=form1.Image1.Canvas.Pixels[x,y]; end;这样还是不对,那我该怎么办呢。。??
可以一行一行读就快多了;Provides indexed access to each line of pixels.
__property void * TBitmap::ScanLine[int Row] = {read=GetScanline};
Description
ScanLine is used only with DIBs (Device Independent Bitmaps) for image editing tools that do low-level pixel work.
就是每行象点的首址;
我的程序在有些象素点要把它的色彩值设为它走围4点(上下左右4点)的平均值,这样也能用scanline吗?
但可改成API函数操作的办法试试。
我认为:
如果各个线程之间空闲时间不多,采用多线程的办法不一定能
加快速度,由于VCL限制多线程访问,不得不用“同步”、“互斥”
的办法减少冲突,进一步降低了多线程的效率;
我的看法不知对不对?!
VCL原来的结构的确实不支持多线程,但后来它用了一个巧妙的方法实现了对多线程的支持。而且其实现的结果是,使用它的程序员在用VCL编写多线程程序时较少的使用烦琐的“同步”、“互斥”,当然VCL的原码并不阻止你的进一步研究。
可大队人马排队通过独木桥,有了独木桥哪还能快?
procedure ConvertThread.Execute;
var
i,j:integer;
begin
for j:=0 to Form1.Image1.Height do begin
for i:=0 to Form1.Image1.Width do begin
form1.Image2.Canvas.Pixels[i,j]:=form1.Image1.Canvas.Pixels[i,j];
end;
end;
end;
这是一个线程的execute中的内容,请各位试试,我运行的时候确实是有些点被绘成白色的空值了,
如果要设成同步模式,那该怎么设呢??对不起,我只有这点分了,请帮帮忙吧
但是,可以用TThread.Synchronize来同步线程对VCL的操作。
请看下面的例子,具体请看Delphi中TThread的帮助。This example shows how to call a button抯 click method in a thread-safe manner:procedure TMyThread.PushTheButton;begin
Button1.Click();
end;procedure TMyThread.Execute;
begin
...
Synchronize(PushTheButton);
...
end;所以,比照这个例子,你应该把画图函数独立成一个过程,然后在ConvertThread.Execute中通过Synchronize来调用。
还有,提示一下,如果你一点点甚至是一条条画图的话,速度是很慢的。建议在内存中开辟一个bitmap,画上去,然后整个复制到界面上。这样快非常之多!
你试一下把循环写到excute里面把描点的过程写到sychronize里面再试一下。因该就可以了。
var
i,j:integer;
begin
for j:=0 to Form1.Image1.Height do begin
for i:=0 to Form1.Image1.Width do begin
Synchronize(drawBitmap);
end;
end;
end;
procedure TMyThread.drawBitmap();begin
form1.Image2.Canvas.Pixels[i,j]:=form1.Image1.Canvas.Pixels[i,j];
end;
首先,如果你的硬件(2cpu?)和操作系统(WinNT? 2000?)不是真正支持多处理器,那么,多线程整体上只会降低速度,而不会提升速度。最多,可能操作性,相应性能好一点。
对于你的程序,要提高速度,最有效的方法,是在内存中画好之后,整体复制到界面控件上。
var
i,j:integer;
begin
for j:=0 to Form1.Image1.Height do begin
for i:=0 to Form1.Image1.Width do begin
Synchronize(drawBitmap(i,j));//这里会出错!!!!!!!!!!
end;
end;
end;procedure mythread.drawBitmap(x,y:integer);
begin
form1.Image2.Canvas.Pixels[x,y]:=form1.Image1.Canvas.Pixels[x,y];
end;这样还是不对,那我该怎么办呢。。??
因此剩下的反感只有两种:
1)直接在当前form中对图片进行处理,但那样必须加上application。processmessages语句,速度实在太慢
2)用多线程的方法。。
所以我想我使用多线程的方法还是没错的吧
但我还是不太清楚为什么要这样做,是因为timage在自动重绘时不能读取其中的数据吗?还忘能有人告诉我。。
非常感谢 Raptor,,我怎么给你分呢??
但我还是不太清楚为什么要这样做,是因为timage在自动重绘时不能读取其中的数据吗?还忘能有人告诉我。。
非常感谢 Raptor,,我怎么给你分呢??