导航:
论坛 -> DELPHI技术
斑竹:liumazi,sephil
作者:
2017/4/18 23:22:31
标题:
加入我的收藏
楼主:
最近在写一个图像处理的软件,这个软件可以从bmp导入图像数据或者用某窗口的句柄作为参数用getdc获得,这2种方法最后都保存在一个tbitmap中,然后用一个二维指针数组保存每个像素的指针,下面是实现的代码: 下面是从某窗口抓图: GetWindowRect(HWND,R); bitmap:=TBitmap.Create; bitmap.Width:=screen.width; bitmap.Height:=screen.Height; DC:=GetDC(gameHWND); //取得屏幕的DC,参数0指的是屏幕 ScreenCanvas:=TCanvas.Create; ScreenCanvas.Handle:=DC; bitmap.Canvas.CopyRect(Rect(0,0,R.Width,R.Height),ScreenCanvas,Rect(0,0,R.Width,R.Height)); 调用处理函数。。。。后附 ScreenCanvas.Free; bitmap.Free; ReleaseDC(0,DC); //释放DC 下面是载入图片: bitmap:=TBitmap.Create; bitmap.LoadFromFile('.\63.bmp'); 调用处理函数。。。。后附 bitmap.free; 下面是处理函数: function TScan.处理函数(bitmap: TBitmap): TStringList var P:array[0..767] of PByteArray; //像素数组 X,Y,W: Integer; R,G,B:Byte; temp:string; begin Result:=TStringList.Create; for Y := 0 to bitmap.Height-1 do begin P[Y]:=bitmap.ScanLine[Y]; //用窗口时这个赋值过程一共耗时3-4秒 end; 其他处理步骤。。。。 //这里不论是图片还是窗口耗时都是几十毫秒 end; 郁闷的地方在于,这个程序用bmp作为数据源时,整个处理过程只要30毫秒以下,但是用别的窗口作为数据源时,耗时竟然要3-4秒,有差别的话倒能理解,但是也不能相差400倍啊。经过测试,问题就出现在处理函数中的那个循环上,请高手帮助,谢谢~如果方便的话,请加我QQ:215709940,或者直接回帖,谢谢!
----------------------------------------------
作者:
radtek (radtek)
★☆☆☆☆
-
盒子活跃会员
2017/4/19 9:31:29
1楼:
一般处理图像要指定图像的PixelFormat,bmp自己本身有这个信息,看你的代码没指定呢。
----------------------------------------------
-
作者:
2017/4/19 10:32:07
2楼:
默认是32bit的,4个字节表示一个像素。
----------------------------------------------
作者:
taday (taday)
★☆☆☆☆
-
普通会员
2017/4/19 13:41:30
3楼:
bitmap := TBitmap.Create; bitmap.PixelFormat:= pf24bit; bitmap.Width := Self.Width; //.width; 加一句 bitmap.PixelFormat:= pf24bit; 速度就一样了
----------------------------------------------
-
作者:
2017/4/19 18:37:55
4楼:
回楼上,图片本来就是32bit的,我处理窗口时,也用的是默认的32bit,同样是32bit,为什么一个快,一个慢?我觉得不是你说的问题。
----------------------------------------------
作者:
radtek (radtek)
★☆☆☆☆
-
盒子活跃会员
2017/4/20 8:44:25
5楼:
你用的bmp图多大? bitmap.Width:=screen.width; bitmap.Height:=screen.Height; 分辨率高的话,这个图不小呢
----------------------------------------------
-
作者:
2017/4/20 11:08:46
6楼:
1366*768 这个跟图的大小没关系 我不明白的是,为什么两种处理方式的耗时相差400倍,虽然数据源不同,但是bitmap是相同的。
----------------------------------------------
作者:
2017/4/20 13:32:02
7楼:
仔细看看ScanLine的代码啊,目测试它的问题。估计O(N2)的速度了。
----------------------------------------------
只有偏执狂才能生存!
作者:
radtek (radtek)
★☆☆☆☆
-
盒子活跃会员
2017/4/20 15:01:35
8楼:
delphi 10.2, bitmap := TBitmap.Create; bitmap.PixelFormat := pf32bit;//添加 加之前,接近10秒,加之后秒出。
----------------------------------------------
-
作者:
radtek (radtek)
★☆☆☆☆
-
盒子活跃会员
2017/4/20 15:02:09
9楼:
procedure TForm1.Button1Click(Sender: TObject); Var R: TRect; bitmap: TBitmap; DC: HWND; ScreenCanvas: TCanvas; Pixeles: TStringList; begin GetWindowRect(self.Handle,R); bitmap := TBitmap.Create; bitmap.PixelFormat := pf32bit; bitmap.Width := screen.Width; bitmap.Height := screen.Height; DC := GetDC(self.Handle); // 取得屏幕的DC,参数0指的是屏幕 ScreenCanvas := TCanvas.Create; ScreenCanvas.Handle := DC; bitmap.Canvas.CopyRect(Rect(0, 0, R.Width, R.Height), ScreenCanvas, Rect(0, 0, R.Width, R.Height)); Pixeles := ConvertPixel(bitmap); ScreenCanvas.Free; bitmap.Free; ReleaseDC(0, DC); // 释放DC end; function TForm1.ConvertPixel(bitmap: TBitmap): TStringList; var P: array of PByteArray; // 像素数组 X, Y, W: Integer; R, G, B: Byte; temp: string; start_time: LONG; stop_time: LONG; begin start_time := GetTickCount; Result := TStringList.Create; setlength(P,bitmap.Width); for Y := 0 to bitmap.Height - 1 do begin P[Y] := bitmap.ScanLine[Y]; // 用窗口时这个赋值过程一共耗时3-4秒 end; stop_time := GetTickCount; ShowMessage(IntToStr(stop_time - start_time)); end;
----------------------------------------------
-
作者:
2017/4/20 18:57:16
10楼:
ScanLine只是返回一个地址值给P[Y],没有对像素操作,花的时间应该少的可以忽略才对。
----------------------------------------------
声明:本人不在论坛询问任何编程问题,请不要将我的帖子当成问题来回答。炒股一天,编程三年,不浪费时间了。 经常在外面,没空,不要找我..
作者:
2017/4/21 0:11:54
11楼:
感谢8楼,问题解决了,也谢谢大家热心回复!
----------------------------------------------
作者:
2017/4/21 8:40:19
12楼:
打死楼主,我也不知道楼主是如何解决的。
----------------------------------------------
(C)(P)Flying Wang