文档章节

Direct2D (16) : 蒙版之 FillOpacityMask() 方法

涂孟超
 涂孟超
发布于 2014/09/26 15:36
字数 616
阅读 14
收藏 0
点赞 0
评论 0

实现蒙版效果有三种途径:使用 FillOpacityMask()、使用 FillGeometry() 方法、使用图层。

FillOpacityMask() 用于处理图像蒙版。
期间用到 ID2D1Bitmap,因为对图像格式要求较高,我通过 TDirect2DCanvas.CreateBitmap() 建立 ID2D1Bitmap 时没有成功。
后来使用了自定义函数直接使用 WIC 加载并转换格式。
蒙版图片是透明图片,将会透过其着色区域看到下层的图片;蒙版图片是以画刷的方式使用的。

实现蒙版区域计算时,还应设置 AntialiasMode 模式为 D2D1_ANTIALIAS_MODE_ALIASED。

FillOpacityMask() 方法的第三个参数(D2D1_OPACITY_MASK_CONTENT 类型):
  //描述蒙板是否包含图形或文本,Direct2D 使用此信息来确定在混合不透明蒙板时要使用哪个 gamma 空间。
D2D1_OPACITY_MASK_CONTENT_GRAPHICS            = 0;
  //蒙板包含图形,在混合时使用 gamma 2.2 颜色空间。
D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL        = 1;
  //蒙板包含非 GDI 文本,用于混合的 gamma 空间源自呈现目标的文字呈现参数。
D2D1_OPACITY_MASK_CONTENT_TEXT_GDI_COMPATIBLE = 2; 
  //蒙板包含使用 GDI 兼容呈现模式呈现的文本,在混合时使用 GDI 呈现的 gamma 空间。


uses Direct2D, D2D1, Wincodec, ActiveX;

{从指定文件建立 ID2D1Bitmap 的函数}
function GetD2D1Bitmap(RenderTarget: ID2D1RenderTarget; imgPath: string): ID2D1Bitmap;
var
  iWicFactory: IWICImagingFactory;
  iWICDecoder: IWICBitmapDecoder;
  iWICFrameDecode: IWICBitmapFrameDecode;
  iFormatConverter: IWICFormatConverter;
begin
  CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, iWicFactory);
  iWicFactory.CreateDecoderFromFilename(PWideChar(imgPath), GUID_NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, iWICDecoder);
  iWicDecoder.GetFrame(0, iWICFrameDecode);
  iWicFactory.CreateFormatConverter(iFormatConverter);
  iFormatConverter.Initialize(iWICFrameDecode, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0, WICBitmapPaletteTypeMedianCut);
  RenderTarget.CreateBitmapFromWicBitmap(iFormatConverter, nil, Result);
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  cvs: TDirect2DCanvas;
  iBitmapBrush: ID2D1BitmapBrush;
  iBitmapPic, iBitmapMark: ID2D1Bitmap;
  rSizeF: TD2DSizeF;
begin
  cvs := TDirect2DCanvas.Create(Canvas, ClientRect);
  iBitmapMark := GetD2D1Bitmap(cvs.RenderTarget, 'C:\Temp\Mark.png');
  iBitmapPic := GetD2D1Bitmap(cvs.RenderTarget, 'C:\Temp\Fern.png');
  cvs.RenderTarget.CreateBitmapBrush(iBitmapPic, nil, nil, iBitmapBrush);

  iBitmapMark.GetSize(rSizeF);
  cvs.BeginDraw;
  cvs.RenderTarget.SetTransform(TD2DMatrix3x2F.Translation((ClientWidth-rSizeF.width)/2, (ClientHeight-rSizeF.height)/2));
  cvs.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
  cvs.RenderTarget.FillOpacityMask(iBitmapMark, iBitmapBrush, D2D1_OPACITY_MASK_CONTENT_GRAPHICS);
  cvs.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
  cvs.EndDraw;
  cvs.Free;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Repaint;
end;


测试图片:C:\Temp\Fern.png



蒙版图片:C:\Temp\Mark.png



蒙版效果:



通过 FillGeometry() 也可以实现上面的效果,但它擅长的是几何蒙版,在这里不如 FillOpacityMask() 简洁:

uses Direct2D, D2D1, Wincodec, ActiveX;

{从指定文件建立 ID2D1Bitmap 的函数}
function GetD2D1Bitmap(RenderTarget: ID2D1RenderTarget; imgPath: string): ID2D1Bitmap;
var
  iWicFactory: IWICImagingFactory;
  iWICDecoder: IWICBitmapDecoder;
  iWICFrameDecode: IWICBitmapFrameDecode;
  iFormatConverter: IWICFormatConverter;
begin
  CoCreateInstance(CLSID_WICImagingFactory, nil, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, iWicFactory);
  iWicFactory.CreateDecoderFromFilename(PWideChar(imgPath), GUID_NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, iWICDecoder);
  iWicDecoder.GetFrame(0, iWICFrameDecode);
  iWicFactory.CreateFormatConverter(iFormatConverter);
  iFormatConverter.Initialize(iWICFrameDecode, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, nil, 0, WICBitmapPaletteTypeMedianCut);
  RenderTarget.CreateBitmapFromWicBitmap(iFormatConverter, nil, Result);
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  cvs: TDirect2DCanvas;
  iBitmapBrush,iBitmapBrushMark: ID2D1BitmapBrush;
  iBitmapPic, iBitmapMark: ID2D1Bitmap;
  rRectF: TD2DRectF;
  rSizeF: TD2DSizeF;
  iRectangleGeometry: ID2D1RectangleGeometry;
begin
  cvs := TDirect2DCanvas.Create(Canvas, ClientRect);
  iBitmapMark := GetD2D1Bitmap(cvs.RenderTarget, 'C:\Temp\Mark.png');
  iBitmapPic := GetD2D1Bitmap(cvs.RenderTarget, 'C:\Temp\Fern.png');

  cvs.RenderTarget.CreateBitmapBrush(iBitmapPic, nil, nil, iBitmapBrush);
  cvs.RenderTarget.CreateBitmapBrush(iBitmapMark, nil, nil, iBitmapBrushMark);

  iBitmapMark.GetSize(rSizeF);
  rRectF := D2D1RectF(0, 0, rSizeF.width, rSizeF.height);
  cvs.BeginDraw;
  cvs.RenderTarget.SetTransform(TD2DMatrix3x2F.Translation((ClientWidth-rSizeF.width)/2, (ClientHeight-rSizeF.height)/2));
  cvs.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
  D2DFactory.CreateRectangleGeometry(rRectF, iRectangleGeometry);
  cvs.RenderTarget.FillGeometry(iRectangleGeometry, iBitmapBrush, iBitmapBrushMark);
  cvs.RenderTarget.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
  cvs.EndDraw;
  cvs.Free;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Repaint;
end;


本文转载自:http://www.cnblogs.com/del/archive/2011/04/05/2005583.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2004
码字总数 14107
作品 0
深圳
程序员
Windows桌面应用程序(1-2-4-7th) DPI和设备无关的像素

要使用Windows图形进行有效编程,您必须了解两个相关的概念: 每英寸点数(DPI) 设备无关像素(DIP)。 我们从DPI开始。这将需要短暂的绕行排版。在印刷术中,类型的大小以称为点的单位来测量。一点...

qq_37422196 ⋅ 01/12 ⋅ 0

Direct2D教程(十)绘制文本

概述 在Direct2D中,文本的绘制是通过DirectWrite来实现的,DirectWrite实际上已经是一个独立的DirectX组件了。关于DirectWrite,我摘录了MSDN的一段文字。 DirectWrite介绍 当今的应用程序应...

吞吞吐吐的 ⋅ 2017/10/17 ⋅ 0

UI设计师SVG动画进阶篇——蒙版动画(上)

蒙版对于UI设计师来说,太熟悉不过了,当然了,可能PS里面用的多一些,AI里面用的少一些,SVG同样支持蒙版,而且借助蒙版,能完成很多神奇的效果。我喜欢称蒙版动画为一种魔术,这是真正的“...

泱泱 ⋅ 2017/05/18 ⋅ 0

关于Direct3D11里汉字显示的一些思考

本系列文章由zhmxy555(毛星云)编写,转载请注明出处。 http://blog.csdn.net/zhmxy555/article/details/8147234 作者:毛星云 邮箱: happylifemxy@163.com 这篇文章里,浅墨希望与大家一起...

长平狐 ⋅ 2012/11/12 ⋅ 0

WinForms篇:DevExpress v16.1新功能介绍

TreeMap Control 在上一个版本(2015.1)中,DevExpress在WPF中增加了 TreeMap Control ,一种用嵌套矩形展示分层和平面数据的方式。此控件推出后,有大批Winforms版用户建议我们将其加入Win...

百mumu ⋅ 2016/06/28 ⋅ 0

数据压缩原理与应用 图像文件的读写和转换(BMP2YUV)实验报告

一、实验原理 1.BMP文件的组成结构 BMP(全称 Bitmap )是Windows操作系统中的标准图像文件格式 ,可以分成两类:设备相关位图(DDB )和设备无关位图( DIB),使用非常广。它采用位映射存...

zgyggy ⋅ 2017/03/22 ⋅ 0

杂谈SharpDx中的WIC组件——我们需要WIC的图片编码功能么?

在前文 SharpDX之Direct2D教程II——加载位图文件和保存位图文件 中,发现在VB2010中不能很好的运用SharpDx中的WIC组件进行图片的编码工作。可能是我的设置问题,也可能是SharpDx对VB2010支持...

万仓一黍 ⋅ 2013/10/08 ⋅ 0

WPF 使用 Direct2D1 画图 绘制基本图形

本文来告诉大家如何在 Direct2D1 绘制基本图形,包括线段、矩形、椭圆 本文是一个系列 WPF 使用 Direct2D1 画图入门 WPF 使用 Direct2D1 画图 绘制基本图形 本文的组织参考Direct2D,对大神表...

lindexi_gd ⋅ 04/19 ⋅ 0

深度解读 - Windows 7核心图形架构细致分析(转贴)

原帖地址:http://technet.microsoft.com/zh-cn/library/ee921514.aspx 如现在大家所想的那样, Windows7 其实是 Windows Vista 的改进版。 Windows 7 在 Windows Vista 的基础上进行了大量的...

迈克老狼1 ⋅ 2012/12/23 ⋅ 0

UI 设计师 SVG 动画进阶篇——蒙版动画(下)

继续上篇 6.动态蒙版位移的产生的扫描效果 这个算是上篇末尾的一点小改进,单独拿出来说,因为这种效果用的场景很多,关键还简单,先看示意图。 设想一下,给文本应用一个蒙版,蒙版的白色部...

泱泱 ⋅ 2017/05/22 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

关于线程的创建

转自自己的笔记: http://note.youdao.com/noteshare?id=87584d4874acdeaf4aa027bdc9cb7324&sub=B49E8956E145476191C3FD1E4AB40DFA 1.创建线程的方法 Java使用Thread类代表线程,所有的线程对......

MarinJ_Shao ⋅ 31分钟前 ⋅ 0

工厂模式学习

1. 参考资料 工厂模式-伯乐在线 三种工厂-思否 深入理解工厂模式 2. 知识点理解 2.1 java三种工厂 简单工厂 工厂模式 抽象工厂 2.2 异同点 逐级复杂 简单工厂通过构造时传入的标识来生产产品...

liuyan_lc ⋅ 43分钟前 ⋅ 0

Java NIO

1.目录 Java IO的历史 Java NIO之Channel Java NIO之Buffer Java NIO之Selector Java NIO之文件处理 Java NIO之Charset Java 可扩展IO 2.简介 “IO的历史”讲述了Java IO API从开始到现在的发...

士别三日 ⋅ 47分钟前 ⋅ 0

[Err] ORA-24344: success with compilation error

从txt文本复制出创建function的脚本,直接执行,然后报错:[Err] ORA-24344: success with compilation error。 突然发现脚本的关键字,居然不是高亮显示。 然后我把脚本前面的空格去掉,执行...

wenzhizhon ⋅ 56分钟前 ⋅ 0

Spring Security授权过程

前言 本文是接上一章Spring Security认证过程进一步分析Spring Security用户名密码登录授权是如何实现得; 类图 调试过程 使用debug方式启动https://github.com/longfeizheng/logback该项目,...

hutaishi ⋅ 今天 ⋅ 0

HAProxy基于KeepAlived实现Web高可用及动静分离

前言 软件负载均衡一般通过两种方式来实现: 基于操作系统的软负载实现 基于第三方应用的软负载实现 LVS是基于Linux操作系统实现的一种软负载,而HAProxy则是基于第三方应用实现的软负载。 ...

寰宇01 ⋅ 今天 ⋅ 0

微软自研处理器的小动作:已经开始移植其他平台的工具链

微软将 Windows 10 、Linux 以及工具链如 C/C++ 和 .NET Core 运行时库、Visual C++ 2017 命令行工具、RyuJIT 编辑器等移植到其自主研发的处理器架构 E2。微软还移植了广泛使用的 LLVM C/C++...

linux-tao ⋅ 今天 ⋅ 0

JS常见this指代总结

1. dom0级事件处理程序的回调函数内 2. dom2级事件处理程序的回调函数内 3. setTimeout 4. setInterval var test = { testfn: function () { console.log(this); }};...

静默行 ⋅ 今天 ⋅ 0

泛型的基本原理

泛型是 JDK1.5 的一个新特性,其实就是一个『语法糖』,本质上就是编译器为了提供更好的可读性而提供的一种小「手段」,虚拟机层面是不存在所谓『泛型』的概念的。 在我看来,『泛型』的存在...

沧海一刀 ⋅ 今天 ⋅ 0

学好Java只需要做到这8点,年薪30W很简单!文末福利赠送!

前言: 大道至简,所以扎实有用的方法,其实都是很简单的,难在踏踏实实的执行过程。今天为大家介绍的就是Java学习的8个看起来非常简单的方法,快学起来吧。 为什么要学习Java? Java是目前最...

java高级架构牛人 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部