895959.comBitBlt可以将源DC中位图复制到目的DC中,且看不惯那种工具也要收费

关于var前缀

一初步认为,用指针就足以在函数内给外部的指针分配内存并传出结果了。但实际不对,外面的指针还从来是nil。必须带上var前缀才行(指针的指针)。

连锁小说

有关搜索:

今天看甚

摸索技术库

回去首页

连锁频道:
Java编程  C#教程  C语言  C++教程  VC教程  Delphi教程  VB教程  工具软件  

总体源码

在Windows中得以将先行准备好的图像复制到突显区域中,那种内存拷贝执行起来是可怜快的。在Windows中提供了二种接纳图形拷贝的格局:通过配备相关位图(DDB)和配备毫无干系位图(DIB)。

界面

就放了多少个按钮而已,名称末尾为C的象征用了COLORONCOLOEvoque格局,为H的代表用了HALFTONE方式。还有壹个Timage控件。

CYourView::OnDraw(CDC* pDC)

{

         CDC memDC;//定义一个兼容DC

         memDC.CreateCompatibleDC(pDC);//创建DC

         CBitmap bmpDraw;

         bmpD      
http://www.bkjia.com/Cyy/493064.htmlwww.bkjia.comtruehttp://www.bkjia.com/Cyy/493064.htmlTechArticle在 Windows中可以将预先准备好的图像复制到显示区域中,这种内存拷贝执行起来是非常快的。在Windows中提供了两种使用图形拷贝的方法:通...

BMP文件读取

因为StretchBlt和BitBlt只必要提供源HDC,不必要用tagBITMAPINFO和原始RGB数据区作为参数,所以直接用了TBitmap控件载入图片文件。

procedure TMainForm.StretchBltDisplay;
var
  bmp : TBitmap ;
  i : Integer ;
  Start : DWORD ;
begin
  Bmp:= TBitmap.Create ;
  bmp.LoadFromFile(FileName);

  Start := GetTickCount ;
  for i := 1 to count do
  begin
    StretchBlt(image1.Canvas.Handle, 0, 0, image1.ClientWidth, image1.ClientHeight,
              bmp.Canvas.Handle, 0,0,bmp.Width,bmp.Height, SRCCOPY);
    image1.Canvas.TextOut(10,10,inttostr(i));
    image1.Refresh;
  end;
  MainForm.Caption := IntToStr(GetTickCount - Start);

  bmp.Free ;
end;

DrawDibDraw和DrawDibDraw都须求使用BMP原始音信做参数,所以只好写了个LoadBmp从文件中读取数据。
因为要把原来音信带出去,所以带了var前缀。

procedure LoadBmp(bmpFile: String; var bmpinfo:TBitmapInfo; var pBmpData:Pointer);
var
  bmf: TBitmapFileHeader;
  imageSize: LongWord;
  Stream: TFileStream;
begin
   try
    Stream:= TFileStream.Create(bmpFile, fmOpenRead or fmShareDenyWrite);
    Stream.Read(bmf, sizeof(Bmf));
    Stream.Read(bmpinfo, sizeof(bmpinfo));
    imageSize:= bmf.bfSize-bmf.bfOffBits;
    stream.Seek(bmf.bfOffBits,0);

    FreeMem(pBmpData);
    GetMem(pBmpData, imageSize);

    Stream.Read(pBmpData^, ImageSize);
  finally
    FreeAndNil(Stream);
  end;
end;

敲定和提议

  • 一味减弱画面的(源图一定比目的图大):StretchBlt、StretchDIBits随便用,先用SetStretchBltMode选COLORONCOLOLacrosse情势,品质充裕了。
  • 务必加大画面的(源图比目的图小):要用StretchBlt、StretchDIBits,用SetStretchBltMode必须选HALFTONE格局。质量无法承受可选DrawDibDraw。
  • 图方便用DrawDibDraw,大概要多耗些财富吧(没规范统计过)。
  • 图形品质须求更高的,啃DirectX、OpenGL、SDL去吗。代码简单,难的是要精晓那么多图形学概念。
  • BLACKNESS
    输出区域为藏莲灰   Turns all output black.
  • DSTINVERT
    反色输出区域   Inverts the destination bitmap.
  • MERGECOPY
    在源和目的间拔取AND操作   Combines the pattern and the source bitmap
    using the Boolean AND operator.
  • MERGEPAINT
    在反色后的目标和源间使用OEnclave操作   Combines the inverted source bitmap
    with the destination bitmap using the Boolean O本田CR-V operator.
  • NOTSRCCOPY
    将反色后的源拷贝到目标区   Copies the inverted source bitmap to the
    destination.
  • PATINVERT
    源和目标间开展XO奥迪Q5操作   Combines the destination bitmap with the
    pattern using the Boolean XO奥迪Q7 operator.
  • SRCAND
    源和目的间开展AND操作   Combines pixels of the destination and
    source bitmaps using the Boolean AND operator.
  • SRCCOPY
    复制源到目标区   Copies the source bitmap to the destination
    bitmap.
  • SRCINVERT
    源和目标间举办XO锐界操作   Combines pixels of the destination and
    source bitmaps using the Boolean XOLacrosse operator.
  • SRCPAINT
    源和目的间开展O奥德赛操作   Combines pixels of the destination and source
    bitmaps using the Boolean O奇骏 operator.
  • WHITENESS
    输出区域为铁锈色   Turns all output white.

源码

DDB可以用MFC中的CBitmap来表示,而DDB一般是储存在财富文件中,在加载时只必要通过财富ID号就足以将图纸装入。BOOL
CBitmap::LoadBitmap( UINT nIDResource
)可以装入钦赐DDB,可是在绘制时务必依赖另1个和眼下绘制DC包容的内存DC来开展。通过CDC::BitBlt(
int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc,
DWOLX570D dwRop
)绘制图形,同时内定光栅操作的体系。BitBlt能够将源DC中位图复制到目的DC中,其中前七个参数为目标区域的坐标,接下去是源DC指针,然后是源DC中的起头坐标,由于BitBlt为等比例复制,所以不要求再行内定长宽,(StretchBlt可以开展缩放)最后贰个参数为光栅操作的花色,可取以下值:

为什么还抱着Delphi不放?

  1. 性价比第2
    敢问品质、便捷、体量俱佳的Windows开发条件,什么人敢和Delphi比?C#,Java是十全十美,可为了2个小效能就跑它个虚拟机,实在划不来啊。C++倒是够sharp,可学习进程太痛心了,代码还不便于写。
  2. 全能
    都说Python好,可自作者眼拙,实在看不出来幸而哪个地方,局限性太大。唯一的裨益是能让新手快速上手编程,还有五个利益是能让你忘记计算机是怎么运作的!
  3. 怀旧
    十几年前自学的事物,从Delphi
    3开头用,有情义了。只要Windows不鸣金收兵对叁拾位程序的协理,作者就会直接用下来。(关于那或多或少,作者要狠狠鄙视Apple一下。)
  4. Delphi 7是经典
    和Visual
    Studio、水果一样,当年Borland的成品也有大小年,逢单的版本就是安静一些。即便轮子有时候得从头伊始造,不过“知其所以然”是乐在其中的事,相信作者!

 

测试结果

假定只关怀结果,只怕对Delphi不屑,那你就无须往下看了,作者先提交结果吗。为你节约点时间。严刻意义上说,BitBlt不属于其它哥仨的阵营,因为不用缩放,所以速度自然快了。放在那里相比较,就当是个Baseline吧。

  1. DrawDibDraw.aspx)最快(1ms级别)。
    不到StretchBlt和StretchDIBits的一半,且不必要用SetStretchBltMode.aspx)设置什么样缩放方式,画质看不出分别。
  2. StretchBlt.aspx)和StretchDIBits.aspx)难分伯仲。
    用了色彩拟合格局(HALFTONE)的话会大大扩张计算量,耗时4倍,比DrawDibDraw慢3个数据级。提出收缩图像时可以用COLORONCOLO昂科威格局,肉眼看不出不一致,但可以比HALFTONE情势提速4倍!
API COLORONCOLOR HALFTONE
BitBlt 400 400
DrawDibDraw 1125 1125
StretchBlt 3000 11406
StretchDIBits 3203 11576
  • 测试用机:CPU: AMD i3 3220,内存: 8G DDCR-VIII 1333,显卡: AMD Radeon
    HD 7700 (对测试结果没影响啊),Windows 10专业版
  • 测试次数:一千次
  • 光阴单位:millisecond(飞秒)
  • COLORONCOLOPAJERO:删除不要求的点。
    这是SetStretchBltMode的参数,钦赐目的设备(区域)的缩放情势。在用StretchDIBits和StretchBlt时必须得设置一个缩放格局,不然,嘿嘿,惨不忍睹。官方认证是:“Deletes
    the pixels. This mode deletes all eliminated lines of pixels without
    trying to preserve their
    information.”,普通话意思大概就是:删除不需要的像素点。该情势删除全体无用的点阵,那个点的兼具新闻都反对保留。
    参见SetStretchBltMode.aspx)。
  • HALFTONE:将源区域的颜色溶入目的区域中去。
    功效同上。官方表明是:“Maps pixels from the source rectangle into
    blocks of pixels in the destination rectangle. The average color
    over the destination block of pixels approximates the color of the
    source
    pixels.”汉语大约意思是:将源矩形区域的像素点信息拟合到目标区域周边的八个像素块中。目标区域七个像素块的水彩值会进行平均,以便最大程度地类似源像素的情调。参见SetStretchBltMode.aspx)。

下边用代码演示那种措施:

关于VFW

DrawDibDraw是VFW(Video for
Windows
.aspx))中的API,关于DrawDibDraw的用法可以参考园子里的DrawDibDraw函数的运用办法。封装文件VFW.pas来自一篇《delphi视频头编程vfw》,出处已不可考,被署名TomNuydens的改动过。

声明

正文是第三观望了求比Stretchblt方法更快的缩放算法的帖子,请参见其中署名为“张辉明”的回复。作者做了优化和局部修正,但DrawDibDraw部分的调用是原文照录的。(其实上文就是自小编Bing了DrawDibDraw时搜到的。)

为啥要测试 StretchBlt, StretchDIBits, DrawDibDraw 的本性

因为录像回看须求很高的显得品质,解码占了很多统计量,留给突显的年月不多,能优化则优化吧。

骨子里将来的CPU跑个视频播放已经绰绰有余了,GPU压根就不用用。就算是用Delphi自带的TImage控件,用Bitmap往里填也得以满意普通播放需要了。假若时光倒流到10年前,这可正是得去研商DirectX、OpenGL了。可惜关于那哥俩,半数以上都是C、C++的财富,小编啃了半天SDL,觉得有个别杀鸡用牛刀。所以就想着先达成须求吧,真的极度了再优化吧。在自作者的AMDi3 3220上,用StretchDIBits播放视频时最多也就跑了22%。

自家的天哪,上一篇博文是2年前的业务了。看来又虚度了2年生活,继续学习。。。
本文算是副产品,正品是应用FFmpeg从随机摄像中生成GIF片段的小程序,等写完了再发。不为其余,只是为了给外甥做动图,且看不惯那种工具也要收费!

常量

FileName定义了Bmp图片文件名,Count定义了测试循环的次数。

FileName='1.bmp';
Count=1000;
FontSize=20;