DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: szliyu112358
今日帖子: 49
在线用户: 12
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 cenunus (cenunus) ★☆☆☆☆ -
普通会员
2017/4/18 23:22:31
标题:
制作图像处理软件遇到的奇怪问题 浏览:1469
加入我的收藏
楼主: 最近在写一个图像处理的软件,这个软件可以从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自己本身有这个信息,看你的代码没指定呢。
----------------------------------------------
-
作者:
男 cenunus (cenunus) ★☆☆☆☆ -
普通会员
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; 速度就一样了
----------------------------------------------
-
作者:
男 cenunus (cenunus) ★☆☆☆☆ -
普通会员
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;
分辨率高的话,这个图不小呢
----------------------------------------------
-
作者:
男 cenunus (cenunus) ★☆☆☆☆ -
普通会员
2017/4/20 11:08:46
6楼: 1366*768
这个跟图的大小没关系
我不明白的是,为什么两种处理方式的耗时相差400倍,虽然数据源不同,但是bitmap是相同的。
----------------------------------------------
作者:
男 nevergrief (孤独骑士) ★☆☆☆☆ -
盒子活跃会员
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;
----------------------------------------------
-
作者:
男 kinneng (kinneng) ★☆☆☆☆ -
盒子活跃会员
2017/4/20 18:57:16
10楼: ScanLine只是返回一个地址值给P[Y],没有对像素操作,花的时间应该少的可以忽略才对。
----------------------------------------------
声明:本人不在论坛询问任何编程问题,请不要将我的帖子当成问题来回答。炒股一天,编程三年,不浪费时间了。 经常在外面,没空,不要找我..
作者:
男 cenunus (cenunus) ★☆☆☆☆ -
普通会员
2017/4/21 0:11:54
11楼: 感谢8楼,问题解决了,也谢谢大家热心回复!
----------------------------------------------
作者:
男 wang_80919 (Flying Wang) ★☆☆☆☆ -
普通会员
2017/4/21 8:40:19
12楼: 打死楼主,我也不知道楼主是如何解决的。
----------------------------------------------
(C)(P)Flying Wang
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行70.3125毫秒 RSS