大家好,我现在在做一个程序,需要复制一个已经创建好的btimap中的一部分到另外一个bitmap中,并保存为jpg图片文件,但是在用户实际使用的过程中,会有一定几率发生复制失败,即保存下来的jpg是白色图片的现象,我对代码进行了测试,发现这个几率很大,使用bitblt也会出现,不管是bitmap还是Canvas都会出现这种现象:
------------代码------------
  tempbit:=tbitmap.Create;
  tempbit.Width:=332;
  tempbit.Height:=212;
  Bmp2Jpg(sbeijing,GetMySelfPath+'photo\temp\temp.JPG');
  tempbit.Canvas.CopyRect(Rect(0,0,332,212),sbeijing.Canvas,rect(0,0,332,212));
  tempbit1:=TBitmap.Create;
  tempbit1.Width:=sbeijing.Width;
  tempbit1.Height:=sbeijing.Height;
  tempbit1.Canvas.CopyRec(tempbit1.Canvas.ClipRect,sbeijing.Canvas,sbeijing.Canvas.ClipRect);
  tempbit1.SaveToFile(GetMySelfPath+'photo\temp\temp1.bmp');
  tempbit.SaveToFile(GetMySelfPath+'photo\temp\temp.bmp');

  Bmp2Jpg(tempbit,PhotoRoot);
  BitBlt(tempbit.Handle,0,0,tempbit.Width,tempbit.Height,sbeijing.Handle,0,0,SRCCOPY);
  tempbit.SaveToFile(GetMySelfPath+'photo\temp\temp2.bmp');
  
  TEMPBIT.Free;
------------代码------------
以上代码中红色部分为我增加测试用的,主要想看一下出现异常时,各种位图是否已经正确生成,发现异常发生时sbeijing保存的temp.bmp可以正常生成外,其他保存的图片全部都是空白。
我怀疑是copyrect时发生了异常,但是我以前做C/C++时候也用过bitblt并没有发生这种现象啊,当时的图片拷贝频率很高,也没有这种现象,delphi是刚接触的开发语言,请教高手是否哪里有问题?像素格式或者其他?

解决方案 »

  1.   

    看你的代码,首先确认sbeijing.bitmap是否有图像?
    sbeijing是什么东东?
    这句 Bmp2Jpg(sbeijing,GetMySelfPath+'photo\temp\temp.JPG'); 具体执行了些什么?
       tempbit:=tbitmap.Create;
       tempbit.Width:=332;
       tempbit.Height:=212;
       Bmp2Jpg(sbeijing,GetMySelfPath+'photo\temp\temp.JPG');
       tempbit.Canvas.CopyRect(Rect(0,0,332,212),sbeijing.Canvas,rect(0,0,332,212));
      

  2.   

    您好,感谢你的回复,我增加那么多红色源码就是为了测试图像是否已经正确生成,sbeijing是上一个程序员起的变量名,是一幅较大的bitmap,这段代码主要是想从sbeijing里面截取一部分图像然后存储,bmp2jpg就是用已经存在的bmp生成jpg格式的图片而已。
    现在的问题是,sbeijing已经正确生成,切可以正确生成图片文件(bmp),但是使用copyrect后就无法拷贝得到正确的图片,所以问题出现在copyrect函数中。
      

  3.   

    sbeijing 是TImage还是 TBitmap?
    如果是TIMAGE,sbeijing里的图片是bmp还是jpg?
    jpg格式的图片在image中直接用Canvas.CopyRect是不行的,需要先进行转换。下面的代码就不会出现空白的现象:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Image1.Picture.LoadFromFile(Edit1.Text);
      Image2.Picture.Bitmap.Assign(Image1.Picture.Graphic);
      Image3.Picture.Bitmap.Width:=332;
      Image3.Picture.Bitmap.Height:=212;
      Image3.Picture.Bitmap.Canvas.CopyRect(Rect(0,0,332,212),Image2.Picture.Bitmap.Canvas,Rect(0,0,332,212) );
    end;
      

  4.   

    非常感谢你,sbeijing是一个tbitmap,不是timage,我忘了说了这个拷贝函数是在另外一个线程中进行操作的,刚从csdn找到一个类似的http://bbs.csdn.net/topics/90123608,说是因为多线程的原因造成的,delphi中使用Synchronize会报错,所以我使用信号量加锁的方式,对临界区进行互斥,但是依旧会出现白色图片的生成
      

  5.   

    你最好在创建Bitmap时指定PixelFormat。
      

  6.   

    改用HBITMP试试还出不出错
      

  7.   

    我也遇到类似的问题,我做的是远程截屏,服务端不断的抓取屏幕生成bitmap,然后压缩成jpeg后传输给客户端。测试中就发现有时候抓屏生成的bitmap不能用SaveToFile方法,提示资源超出,但把这个bitmap 转成 jpeg 后,jpeg可以保存,而且图像是正确的。然后又试图用 BitBlt 把这个 bitmap 拷到另一幅 bitmap 里,则另一幅 bitmap 可以保存,但内容是空白的。最后不用 BitBlt ,改用 ScanLline 方法把这个 bitmap 拷到另一幅 bitmap 里,则另一幅 bitmap 可以保存,图像也是正确的,真的非常奇怪。
    给我的感觉有两个,一个好像抓屏(用的是BitBlt)有时机问题,可能有些情况下不能抓屏(我测试时飞快移动窗口,就会出现上面的问题),但目前为止也没有得到论证。另一个感觉BitBlt拷贝图片速度确实非常快,但好像有时不成功(当然也可能是TBitmap的Canvas本身有问题或者Canvas的Handle本身就有问题),可也没有测试出来。