BitBlt能够将源DC中位图复制到目的DC中,且看不惯那种工具也要收费

自笔者的天哪,上一篇博文是2年前的事体了。看来又虚度了2年生活,继续攻读。。。
正文算是副产品,正品是行使FFmpeg从随机视频中生成GIF片段的小程序,等写完了再发。不为别的,只是为着给外甥做动图,且看不惯那种工具也要收费!

 

怎么还抱着Delphi不放?

  1. 性价比第二
    敢问质量、便捷、体量俱佳的Windows开发环境,什么人敢和Delphi比?C#,Java是了不起,可为了一个小作用就跑它个虚拟机,实在划不来啊。C++倒是够sharp,可学习进度太难熬了,代码还不易于写。
  2. 全能
    都说Python好,可本人眼拙,实在看不出来还好哪个地方,局限性太大。唯一的补益是能让新手飞快上手工编织程,还有1个好处是能让您忘掉计算机是怎么运作的!
  3. 怀旧
    十几年前自学的东西,从Delphi
    3开首用,有心思了。只要Windows不鸣金收兵对叁九位程序的支撑,作者就会直接用下来。(关于那或多或少,笔者要狠狠鄙视Apple一下。)
  4. Delphi 7是经典
    和Visual
    Studio、水果一样,当年Borland的成品也有大小年,逢单的版本正是安静一些。尽管轮子有时候得从头开端造,可是“知其所以然”是乐在在那之中的事,相信本身!

在Windows中能够将优先准备好的图像复制到显示区域中,那种内部存款和储蓄器拷贝执行起来是十一分快的。在Windows中提供了三种选择图形拷贝的法子:通过设备相关位图(DDB)和配备毫无干系位图(DIB)。

源码

连锁文章

有关搜索:

今日看甚

查找技术库

回去首页

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

测试结果

一经只关怀结果,大概对Delphi不屑,那你就无需往下看了,笔者先提交结果吗。为你节约点时间。严峻意义上说,BitBlt不属于任何哥仨的阵营,因为不用缩放,所以速度自然快了。放在那里相比较,就当是个Baseline吧。

  1. DrawDibDraw.aspx)最快(1ms级别)。
    不到StretchBlt和StretchDIBits的1/2,且不需求用SetStretchBltMode.aspx)设置哪些缩放格局,画质看不出分别。
  2. StretchBlt.aspx)和StretchDIBits.aspx)难分伯仲。
    用了色彩拟合情势(HALFTONE)的话会大大扩充总结量,耗费时间4倍,比DrawDibDraw慢一个数据级。提出减弱图像时得以用COLORONCOLO瑞虎形式,肉眼看不出区别,但能够比HALFTONE形式提速4倍!
API COLORONCOLOR HALFTONE
BitBlt 400 400
DrawDibDraw 1125 1125
StretchBlt 3000 11406
StretchDIBits 3203 11576
  • 测试用机:CPU: 速龙 i3 3220,内存: 8G DD中华VIII 1333,显卡: 英特尔 Radeon
    HD 7700 (对测试结果没影响吗),Windows 10专业版
  • 测试次数:一千次
  • 日子单位:millisecond(阿秒)
  • COLORONCOLO帕杰罗:删除不须求的点。
    这是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)。

BMP文件读取

因为StretchBlt和BitBlt只需求提供源HDC,不须求用tagBITMAPINFO和原始SportageGB数据区作为参数,所以一直用了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;

DDB能够用MFC中的CBitmap来表示,而DDB一般是储存在资源文件中,在加载时只须求经过能源ID号就能够将图片装入。BOOL
CBitmap::LoadBitmap( UINT nIDResource
)能够装入钦点DDB,可是在绘制时务必借助另二个和当下绘制DC包容的内部存款和储蓄器DC来拓展。通过CDC::BitBlt(
int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc,
DWO宝马X3D dwRop
)绘制图形,同时钦定光栅操作的类型。BitBlt能够将源DC中位图复制到目标DC中,在那之中前八个参数为指标区域的坐标,接下去是源DC指针,然后是源DC中的初叶坐标,由于BitBlt为等比例复制,所以不要求重新钦赐长宽,(StretchBlt能够开始展览缩放)最后一个参数为光栅操作的档次,可取以下值:

敲定和建议

  • 单单减少画面包车型客车(源图一定比目的图大):StretchBlt、StretchDIBits随便用,先用SetStretchBltMode选COLORONCOLOXC60情势,质量丰富了。
  • 务必加大画面包车型大巴(源图比目的图小):要用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
    在反色后的指标和源间使用OHaval操作   Combines the inverted source bitmap
    with the destination bitmap using the Boolean O奥迪Q5 operator.
  • NOTSRCCOPY
    将反色后的源拷贝到目的区   Copies the inverted source bitmap to the
    destination.
  • PATINVERT
    源和目标间展开XOR操作   Combines the destination bitmap with the
    pattern using the Boolean XO索罗德 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本田CR-V操作   Combines pixels of the destination and source
    bitmaps using the Boolean OSportage operator.
  • WHITENESS
    输出区域为暗灰   Turns all output white.

声明

本文是第二看到了求比Stretchblt方法更快的缩放算法的帖子,请参见在那之中署名为“张辉明”的还原。作者做了优化和一部分修正,但DrawDibDraw部分的调用是原来的书文照录的。(其实上文正是自己Bing了DrawDibDraw时搜到的。)

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中提供了两种使用图形拷贝的方法:通...

关于var前缀

一开端认为,用指针就能够在函数内给外部的指针分配内部存储器并传出结果了。但实在不对,外面包车型地铁指针还一贯是nil。必须带上var前缀才行(指针的指针)。

上面用代码演示那种措施:

总体源码

怎么要测试 StretchBlt, StretchDIBits, DrawDibDraw 的习性

因为录制重播要求很高的来得质量,解码占了诸多总括量,留给展现的岁月不多,能优化则优化吧。

骨子里未来的CPU跑个录制播放已经绰绰有余了,GPU压根就无需用。就算是用Delphi自带的TImage控件,用Bitmap往里填也得以满足常常播放要求了。如若时光倒流到10年前,那可真是得去切磋DirectX、OpenGL了。可惜关于那哥俩,大多数都以C、C++的能源,笔者啃了半天SDL,觉得多少杀鸡用牛刀。所以就想着先完结须要吧,真的十二分了再优化吧。在本人的Inteli3 3220上,用StretchDIBits播放摄像时最多也就跑了22%。

常量

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

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

界面

就放了多少个按钮而已,名称末尾为C的表示用了COLORONCOLO昂Cora格局,为H的象征用了HALFTONE情势。还有3个提姆age控件。

关于VFW

DrawDibDraw是VFW(Video for
Windows
.aspx))中的API,关于DrawDibDraw的用法能够参照园子里的DrawDibDraw函数的使用方法。封装文件VFW.pas来自一篇《delphi录制头编制程序vfw》,出处已不可考,被署名汤姆Nuydens的修改过。

相关文章