Delphi图像处理 -- 图像显示
2009-10-30 11:16
344 查看
阅读提示:
《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM。
《C++图像处理》系列以代码清晰,可读性为主,全部使用C++代码。
尽可能保持二者内容一致,可相互对照。 本文代码必须包括文章《Delphi图像处理 -- 数据类型及公用过程》中的ImageData.pas单元和《Delphi图像处理 -- 图像合成》中除例子外的全部代码。
Delphi的TCanvas以及派生类提供了显示TGraphic图像的方法Draw,其实这个方法本身并没有显示图像的功能,只是反过来调用了一下TGraphic的Draw方法。TGraphic本身是个抽象类,其Draw方法也是个纯虚方法,所以TGraphic的所有派生类必须提供一个具体的Draw方法。TGraphic的主要派生类TBitmap也有一个Draw方法,但是该方法只能利用其Transparent属性显示透明背景图像,而不能正确显示带Alpha通道的32位图像,即使Delphi2009以上版本的TGraphic增添了一个SupportsPartialTransparency属性,但TBitmap也还是没法直接显示ARGB像素格式的图像,因为TBitmap调用的是Windows API的AlphaBlend函数,该函数似乎只能显示PARGB格式像素的图像,而且TGraphic的SupportsPartialTransparency属性还是只读性质的。
GDI+的TGpGraphics的系列DrawImage方法画ARGB32位图像倒是很好的,但如果图像真的含Alpha信息时,显示的速度却是较慢,大家可以用2张较大的图片试一下,一张含Alpha,一张不含Alpha,对比一下就知道了。
因为本系列图像处理过程中有多个方法会使Alpha分量发生变化,即使该图像原来不含Alpha信息,所以有必要写图像显示过程。而且,如果在应用程序中只是需要显示处理过的图像,就不必再将TImageData类型转换为TGraphic或者TGpBitmap了,直接使用本文的显示过程无疑是很方便的。
本文的图像显示是利用《Delphi图像处理 -- 图像合成》中的图像合成过程_DoMixer来完成的,因此,必须包括《Delphi图像处理 -- 图像合成》中除例子外的全部代码:
本文介绍的只是最基本的显示过程,还可以有拉伸形式和几何变换形式的图像显示方式,参照《Delphi图像处理 -- 几何变换(上)》和《Delphi图像处理 -- 几何变换(下)》代码可以很容易完成。
上面代码中例子的显示效果同《Delphi图像处理 -- 图像合成》的第二副效果图:
《Delphi图像处理》系列使用GDI+单元下载地址和说明见文章《GDI+ for VCL基础 -- GDI+ 与 VCL》。
因水平有限,错误在所难免,欢迎指正和指导。邮箱地址:maozefa@hotmail.com
这里可访问《Delphi图像处理 -- 文章索引》。
《Delphi图像处理》系列以效率为侧重点,一般代码为PASCAL,核心代码采用BASM。
《C++图像处理》系列以代码清晰,可读性为主,全部使用C++代码。
尽可能保持二者内容一致,可相互对照。 本文代码必须包括文章《Delphi图像处理 -- 数据类型及公用过程》中的ImageData.pas单元和《Delphi图像处理 -- 图像合成》中除例子外的全部代码。
Delphi的TCanvas以及派生类提供了显示TGraphic图像的方法Draw,其实这个方法本身并没有显示图像的功能,只是反过来调用了一下TGraphic的Draw方法。TGraphic本身是个抽象类,其Draw方法也是个纯虚方法,所以TGraphic的所有派生类必须提供一个具体的Draw方法。TGraphic的主要派生类TBitmap也有一个Draw方法,但是该方法只能利用其Transparent属性显示透明背景图像,而不能正确显示带Alpha通道的32位图像,即使Delphi2009以上版本的TGraphic增添了一个SupportsPartialTransparency属性,但TBitmap也还是没法直接显示ARGB像素格式的图像,因为TBitmap调用的是Windows API的AlphaBlend函数,该函数似乎只能显示PARGB格式像素的图像,而且TGraphic的SupportsPartialTransparency属性还是只读性质的。
GDI+的TGpGraphics的系列DrawImage方法画ARGB32位图像倒是很好的,但如果图像真的含Alpha信息时,显示的速度却是较慢,大家可以用2张较大的图片试一下,一张含Alpha,一张不含Alpha,对比一下就知道了。
因为本系列图像处理过程中有多个方法会使Alpha分量发生变化,即使该图像原来不含Alpha信息,所以有必要写图像显示过程。而且,如果在应用程序中只是需要显示处理过的图像,就不必再将TImageData类型转换为TGraphic或者TGpBitmap了,直接使用本文的显示过程无疑是很方便的。
本文的图像显示是利用《Delphi图像处理 -- 图像合成》中的图像合成过程_DoMixer来完成的,因此,必须包括《Delphi图像处理 -- 图像合成》中除例子外的全部代码:
function GetBitmapInfoHeader(const Data: TImageData): TBitmapInfoHeader; begin Result.biSize := Sizeof(TBitmapInfoHeader); Result.biWidth := Data.Width; Result.biHeight := Data.Height; Result.biPlanes := 1; Result.biBitCount := (Data.PixelFormat shr 8) and $ff; Result.biCompression := BI_RGB; end; procedure GetDCImageData(DC: HDC; x, y: Integer; var Data: TImageData; pbi: TBitmapInfo); var saveBitmap, Bitmap: HBITMAP; memDC: HDC; begin Bitmap := CreateCompatibleBitmap(DC, Data.Width, Data.Height); try memDC := CreateCompatibleDC(DC); saveBitmap := SelectObject(memDC, Bitmap); try BitBlt(memDC, 0, 0, Data.Width, Data.Height, DC, x, y, SRCCOPY); finally SelectObject(memDC, saveBitmap); DeleteDC(memDC); end; GetDIBits(DC, bitmap, 0, Data.Height, Data.Scan0, pbi, DIB_RGB_COLORS); finally DeleteObject(Bitmap); end; end; procedure BitBltImageData(DC: HDC; x, y: Integer; const Data: TImageData; pbi: TBitmapInfo); var saveBitmap, Bitmap: HBITMAP; memDC: HDC; begin Bitmap := CreateDIBItmap(DC, pbi.bmiHeader, CBM_INIT, Data.Scan0, pbi, DIB_RGB_COLORS); memDC := CreateCompatibleDC(DC); saveBitmap := SelectObject(memDC, Bitmap); try BitBlt(DC, x, y, Data.Width, Data.Height, memDC, 0, 0, SRCCOPY); finally SelectObject(memDC, saveBitmap); DeleteDC(memDC); DeleteObject(Bitmap); end; end; procedure ImageDraw(DC: HDC; x, y: Integer; const Data: TImageData; Alpha: Single = 1); var pbi: TBitmapInfo; dstR, srcR: TRect; alphaI: Integer; dst, src: TImageData; pData: PImageData; begin if GetClipBox(DC, dstR) <= NULLREGION then Exit; alphaI := Round(Alpha * 256); if alphaI < 0 then Exit; if alphaI > 256 then alphaI := 256; if (alphaI = 256) and not Data.AlphaFlag and ((Data.Width shl 2) = -Data.Stride) then begin pbi.bmiHeader := GetBitmapInfoHeader(Data); pData := @Data; _InvertScan0(pData^); BitBltImageData(DC, x, y, Data, pbi); _InvertScan0(pData^); Exit; end; dstR.Left := 0; dstR.Top := 0; srcR := Rect(x, y, Data.Width + x, Data.Height + y); if not IntersectRect(dstR, dstR, srcR) then Exit; if x < 0 then x := -x else x := 0; if y < 0 then y := -y else y := 0; src := GetSubImageData(Data, x, y, dstR.Right - dstR.Left, dstR.Bottom - dstR.Top); dst := NewImageData(src.Width, src.Height); dst.AlphaFlag := False; pbi.bmiHeader := GetBitmapInfoHeader(dst); if (alphaI < 256) or Data.AlphaFlag then GetDCImageData(DC, dstR.Left, dstR.Top, dst, pbi); _InvertScan0(dst); _DoMixer(dst, src, alphaI); _InvertScan0(dst); BitBltImageData(DC, dstR.Left, dstR.Top, dst, pbi); FreeImageData(dst); end; procedure TForm1.Button3Click(Sender: TObject); var source: TGpBitmap; dest: TBitmap; tmp: TJpegImage; src, dst: TImageData; begin dest := TBitmap.Create; tmp := TJpegImage.Create; tmp.LoadFromFile('..\..\media\IMG_9440_mf.jpg'); dest.Assign(tmp); tmp.Free; source := TGpBitmap.Create('..\..\media\xmas_011.png'); dst := GetBitmapData(dest); src := LockGpBitmap(source); ImageDraw(Canvas.Handle, 0, 0, dst); ImageDraw(Canvas.Handle, dst.Width, 0, src); ImageMixer(dst, src, 1); UnlockGpBitmap(source, src); ImageDraw(Canvas.Handle, dst.Width + src.Width, 0, dst); dest.Free; source.Free; end;ImageDraw过程比GDI+的TGpGraphics.DrawImage方法要快,特别是显示png之类的图片。
本文介绍的只是最基本的显示过程,还可以有拉伸形式和几何变换形式的图像显示方式,参照《Delphi图像处理 -- 几何变换(上)》和《Delphi图像处理 -- 几何变换(下)》代码可以很容易完成。
上面代码中例子的显示效果同《Delphi图像处理 -- 图像合成》的第二副效果图:
《Delphi图像处理》系列使用GDI+单元下载地址和说明见文章《GDI+ for VCL基础 -- GDI+ 与 VCL》。
因水平有限,错误在所难免,欢迎指正和指导。邮箱地址:maozefa@hotmail.com
这里可访问《Delphi图像处理 -- 文章索引》。
相关文章推荐
- 用python简单处理图片(1):打开\显示\保存图像
- cacti不能显示图像数据故障处理办法
- FPGA图像处理之多画面显示
- Delphi图像处理 -- 文章索引
- delphi 图像处理 二值化
- 请教:vc与delphi在图像处理开发方面有何优劣?
- 使用CImage类处理图像显示与格式转换(转)
- DELPHI中图像的显示效果
- 32位图像处理库 delphi简单实现(转贴)
- Delphi图像处理 -- 数据类型及公用过程
- Delphi基本图像处理方法汇总
- Delphi制作图像特殊显示效果
- OpenCV-将图像作平滑处理并显示
- Delphi图像处理 -- 设置图像关键颜色
- 【OpenCV3图像处理】图像载入、显示、保存
- 用python简单处理图片(1):打开\显示\保存图像
- 处理2D图像和纹理——使用SpriteBatch类显示2D图像:加载和绘制图像
- OpenCV 利用MFC的Picture控件显示和处理图像
- 【数字图像处理】花样显示图像
- Delphi图像处理 -- 彩色浮雕