本系列文章目录:

SharpDX之Direct2D教程I——简单示例和Color(颜色)

绘制位图是绘制操作的不可缺少的一部分。在Direct2D中绘制位图,必须先利用WIC组件将位图加载到内存中,再绘制到RenderTarget中去

在SharpDX中绘制位图,分成两个部分:

利用WIC在SharpDX中加载位图,生成Bitmap对象

利用RenderTarget对象的DrawBitmap方法把Bitmap对象绘制到RenderTarget中去

利用WIC在SharpDX中加载位图文件

利用WIC在SharpDX中绘制位图文件的核心内容就是把位图文件转换为Bitmap对象。它的操作过程如下:

1、创建WIC的ImagingFactory类。

2、根据位图文件创建BitmapDecoder对象(实际上调用系统解码器解析位图文件)。

BitmapDecoder对象有1个属性和1个函数

FrameCount属性:只读属性,说明该位图对象包含的帧数。一般gif文件能包含多个帧,其余格式的一般只有1个帧

GetFrame函数:返回指定帧对象。参数index是整形,说明是第几帧(从0开始)。返回的是BitmapFrameDecode对象

3、利用BitmapDecoder对象的GetFrame函数,返回指定帧的BitmapFrameDecode对象。(参数index一般是0,返回第1帧)

一般情况下,到此就可以了。但是,位图格式有很多,你可能不是很确定你的位图格式是否兼容SharpDX的Bitmap对象。因此,比较好的做法是继续下面的步骤,将位图格式转换为兼容SharpDX的Bitmap对象

4、创建FormatConverter对象。该对象负责进行格式转换。

5、调用FormatConverter对象的Initialize方法,进行格式转换。

6、最后,利用Bitmap对象的FromWicBitmap函数将之前的FormatConverter对象转换为SharpDX的Bitmap对象

和Windows API Code Pack 1.1中的Direct2D略有不同的是,BitmapFrameDecode对象和FormatConverter对象都继承BitmapSource对象,省去了一个转换的过程

下面是代码

 
    Protected Function LoadBitmap(Render As D2D.RenderTarget, File As String, FrameIndex As Integer) As D2D.Bitmap
        Dim Decoder As New WIC.BitmapDecoder(_ImagingFactory, File, DX.IO.NativeFileAccess.Read, WIC.DecodeOptions.CacheOnLoad)

If FrameIndex > Decoder.FrameCount - 1 OrElse FrameIndex < 0 Then FrameIndex = 0

Dim Source As WIC.BitmapFrameDecode = Decoder.GetFrame(FrameIndex)

Dim Converter As New WIC.FormatConverter(_ImagingFactory)
        Converter.Initialize(Source, WIC.PixelFormat.Format32bppPBGRA)

Return D2D.Bitmap.FromWicBitmap(Render, Converter)
    End Function

利用RenderTarget对象的DrawBitmap方法把Bitmap对象绘制到RenderTarget中去

下面是DrawBitmap方法的原型定义:

 
Public Sub DrawBitmap(bitmap As D2D.Bitmap, destinationRectangle As DX.RectangleF, opacity As Single, interpolationMode As D2D.BitmapInterpolationMode, sourceRectangle As DX.RectangleF)
Public Sub DrawBitmap(bitmap As D2D.Bitmap, opacity As Single, interpolationMode As D2D.BitmapInterpolationMode)
Public Sub DrawBitmap(bitmap As D2D.Bitmap, destinationRectangle As DX.RectangleF, opacity As Single, interpolationMode As D2D.BitmapInterpolationMode)
Public Sub DrawBitmap(bitmap As D2D.Bitmap, opacity As Single, interpolationMode As D2D.BitmapInterpolationMode, sourceRectangle As DX.RectangleF)

参数的意义如下:

bitmap:要绘制的Bitmap对象

destinationRectangle:绘制在RenderTarget对象上的目标范围。缺省是在RenderTarget对象的左上角,宽高是Bitmap对象的宽高

opacity:不透明度

interpolationMode:图像缩放时的插值算法,是个枚举

sourceRectangle:要绘制的源目标范围。缺省是Bitmap对象的整个范围

下面是示例代码

 
Public Class clsSharpDXLoadBitmap
    Inherits clsSharpDXSampleBase

Protected _ImagingFactory As WIC.ImagingFactory

Public Shadows Sub CreateDeviceResource(Target As Control)
        MyBase.CreateDeviceResource(Target)
        _ImagingFactory = New WIC.ImagingFactory
    End Sub

Public Function LoadBitmap(File As String, Optional FrameIndex As Integer = 0) As D2D.Bitmap
        Return LoadBitmap(_RenderTarget, File, FrameIndex)
    End Function

Protected Function LoadBitmap(Render As D2D.RenderTarget, File As String, FrameIndex As Integer) As D2D.Bitmap
        Dim Decoder As New WIC.BitmapDecoder(_ImagingFactory, File, DX.IO.NativeFileAccess.Read, WIC.DecodeOptions.CacheOnLoad)

If FrameIndex > Decoder.FrameCount - 1 OrElse FrameIndex < 0 Then FrameIndex = 0

Dim Source As WIC.BitmapFrameDecode = Decoder.GetFrame(FrameIndex)

Dim Converter As New WIC.FormatConverter(_ImagingFactory)
        Converter.Initialize(Source, WIC.PixelFormat.Format32bppPBGRA)

Return D2D.Bitmap.FromWicBitmap(Render, Converter)
    End Function

Public Shadows Sub Render()
        With _RenderTarget

.BeginDraw()

.Clear(DX.Color.Honeydew.ToColor4)

Dim B As D2D.Bitmap = LoadBitmap("216.png")

.DrawBitmap(B, 1, SharpDX.Direct2D1.BitmapInterpolationMode.NearestNeighbor, New DX.RectangleF(0, 0, 260, 260))

.EndDraw()
        End With
    End Sub
End Class

利用WIC保存图片

WIC既能负责图片的解码,也能负责图片的编码。我们也可以利用WIC编码图片。

在调试的时候出了问题,先看看下面两段代码

 
Public Class Class1
    Public Shared Sub Test()
        Dim wicFactory As WIC.ImagingFactory = New WIC.ImagingFactory
        Dim F As String = "333.png"

If (File.Exists(F)) Then File.Delete(F)
        Dim spStream As WIC.WICStream = New WIC.WICStream(wicFactory, F, NativeFileAccess.Write)

Dim spBitmapEncoder As WIC.PngBitmapEncoder = New WIC.PngBitmapEncoder(wicFactory)

spBitmapEncoder.Initialize(spStream)

End Sub
End Class

上面的代码是用VB2010写的,仅仅写到PngBitmapEncoder对象的Initialize方法。

再看看下面这段代码,用的是C# 2010写的

 
    class Class1
    {
       public static  void test()
        {
            ImagingFactory  wicFactory = new ImagingFactory();
            string F = "333.png";
           
            if (File.Exists(F))  File.Delete(F);

WICStream  stream = new WICStream(wicFactory, F, NativeFileAccess.Write);
            PngBitmapEncoder  encoder = new PngBitmapEncoder(wicFactory);
            encoder.Initialize(stream);

}
    }

可以看出,两段代码没什么不同(仅仅是语法上的不同而已),但是VB2010的代码在执行到Initialize时总是报错(内部错误),而C#2010在执行到Initialize方法很顺利的完成了。两段代码引用的是同一个动态库SharpDX的2.5.0的库。

我解释不出是什么原因,只能归结于SharpDX自身的原因了。

不过,我发现一个问题,写在这儿,给大家一个参考,也许谁能给出解决方案。(或者是我的设置有问题?)

在VB2010中,PngBitmapEncoder类的初始方法只能看到两个,New(Object)和New(IntPtr)

在C#2010中,PngBitmapEncoder类的初始方法能看到六个,除了上面的两个,还多了很多

打开SharpDX.Direct2D1.xml中也看到PngBitmapEncoder对象的初始方法有六个

难道SharpDX真的不能很好的运用于VB2010中么?

最后贴一段SharpDX中自带示例中的WIC保存图片的代码

 
using System;
using System.IO;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.DXGI;
using SharpDX.IO;
using SharpDX.WIC;

using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using Bitmap = SharpDX.WIC.Bitmap;
using PixelFormat = SharpDX.Direct2D1.PixelFormat;

namespace RenderToWicApp
{
    internal static class Program
    {
        private static void Main()
        {
            var wicFactory = new ImagingFactory();
            var d2dFactory = new SharpDX.Direct2D1.Factory();

string filename = "output.png";
            const int width = 512;
            const int height = 512;

var rectangleGeometry = new RoundedRectangleGeometry(d2dFactory, new RoundedRectangle() { RadiusX = 32, RadiusY = 32, Rect = new RectangleF(128, 128, width - 128 * 2, height-128 * 2) });

var wicBitmap = new Bitmap(wicFactory, width, height, SharpDX.WIC.PixelFormat.Format32bppBGR, BitmapCreateCacheOption.CacheOnLoad);

var renderTargetProperties = new RenderTargetProperties(RenderTargetType.Default, new PixelFormat(Format.Unknown, AlphaMode.Unknown), 0, 0, RenderTargetUsage.None, FeatureLevel.Level_DEFAULT);

var d2dRenderTarget = new WicRenderTarget(d2dFactory, wicBitmap, renderTargetProperties);

var solidColorBrush = new SolidColorBrush(d2dRenderTarget, Color.White);

d2dRenderTarget.BeginDraw();
            d2dRenderTarget.Clear(Color.Black);
            d2dRenderTarget.FillGeometry(rectangleGeometry, solidColorBrush, null);
            d2dRenderTarget.EndDraw();

if (File.Exists(filename))
                File.Delete(filename);

var stream = new WICStream(wicFactory, filename, NativeFileAccess.Write);
            var encoder = new PngBitmapEncoder(wicFactory);
            encoder.Initialize(stream);

var bitmapFrameEncode = new BitmapFrameEncode(encoder);
            bitmapFrameEncode.Initialize();
            bitmapFrameEncode.SetSize(width, height);
            var pixelFormatGuid = SharpDX.WIC.PixelFormat.FormatDontCare;
            bitmapFrameEncode.SetPixelFormat(ref pixelFormatGuid);
            bitmapFrameEncode.WriteSource(wicBitmap);

bitmapFrameEncode.Commit();
            encoder.Commit();

bitmapFrameEncode.Dispose();
            encoder.Dispose();
            stream.Dispose();

System.Diagnostics.Process.Start(Path.GetFullPath(Path.Combine(Environment.CurrentDirectory,filename)));
        }
    }
}

SharpDX之Direct2D教程II——加载位图文件和保存位图文件的更多相关文章

  1. [译]Vulkan教程(31)加载模型

    [译]Vulkan教程(31)加载模型 Loading models 加载模型 Introduction 入门 Your program is now ready to render textured ...

  2. [Android]异步加载图片,内存缓存,文件缓存,imageview显示图片时增加淡入淡出动画

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3574131.html  这个可以实现ImageView异步加载 ...

  3. 安装Win7或者XP系统用虚拟光驱加载Win7或者XP镜像 iso文件xp win7wim文件

    安装Win7或者XP系统用虚拟光驱加载Win7或者XP镜像 iso文件xp win7wim文件 http://pcedu.pconline.com.cn/teach/xt/1201/2657834_8 ...

  4. 用MVVM模式开发中遇到的零散问题总结(5)——将动态加载的可视元素保存为图片的控件,Binding刷新的时机

    原文:用MVVM模式开发中遇到的零散问题总结(5)--将动态加载的可视元素保存为图片的控件,Binding刷新的时机 在项目开发中经常会遇到这样一种情况,就是需要将用户填写的信息排版到一张表单中,供打 ...

  5. cordova加载层、进度条、文件选择插件

    在做cordova项目的时候,感觉应用的响应速度跟原生应用比相差甚远,一个主要问题就是如加载层.进度条等弹出对话框的效率不行.毕竟项目中的这些弹框都是用dom拼成的,dom的渲染效率和原生控件比起来慢 ...

  6. 网站加载css/js/img等静态文件失败

    网站加载css/js/img等静态文件失败,报网站http服务器内部500错误.而服务器中静态文件存在且权限正常. 从浏览器中直接访问文件,出来乱码.这种问题原因在于iis中该网站mime配置报错,不 ...

  7. ThinkPHP第三天(公共函数Common加载,dump定义,模板文件,定义替换__PUBLIC__)

    1.公共函数定义 自动加载:在项目的common文件夹中定义,公共函数文件命名规则为common.php,只有命名成common.php才能被自动载入. 动态加载:可以修改配置项‘LOAD_EXT_F ...

  8. 加载所有jar包下指定文件

    加载所有jar包下指定文件: 如spring中加载 META-INF/spring.handlers 加载 org.springframework.core.io.support.Properties ...

  9. 精尽MyBatis源码分析 - MyBatis初始化(二)之加载Mapper接口与XML映射文件

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

随机推荐

  1. EasyUI个人项目晒图(续)

    晒自己做的一个管理系统(清新风格)EasyUI 这是自己上一次的文章了,只是给大家看一下自己的美观度是不是还是停留在新手的阶段!反正我自己认为我已经不是一个新手了吧!虽然技术永远学不完,我可以说,我和 ...

  2. csharp: json to csharp

    http://json2csharp.com/ http://jsonclassgenerator.codeplex.com/ http://jsonutils.com/ JSON生成类文件 http ...

  3. 泛函编程(14)-try to map them all

    虽然明白泛函编程风格中最重要的就是对一个管子里的元素进行操作.这个管子就是这么一个东西:F[A],我们说F是一个针对元素A的高阶类型,其实F就是一个装载A类型元素的管子,A类型是相对低阶,或者说是基础 ...

  4. API的非向后兼容性无论如何通常代表着一种比较差的设计

    不管一个类库或者工具方法实现多么的好,如果无法做到向后兼容性,通常会给用户带来很大的升级成本,很多对此的依赖如果希望在后续的升级和维护期间使用该类库的其他新增特性或者好处,将不得不推迟升级亦或是被迫接 ...

  5. ssh 客户端远程vi文本文件中文乱码(亲测)

    由于是生产环境,且非笔者控制,为了避免影响系统全局,仅对本session有效 export LANG="zh_CN.UTF-8"export LANG="zh_CN.GB ...

  6. iOS设计模式之备忘录模式

    备忘录模式 基本理解 这个模式有三个关键角色:原发器(Originator).备忘录(Memento).看管人(caretaker).三者的基本关系是:原发器创建一个包含其状态的备忘录,并传给看管人. ...

  7. Struts2(十七)验证框架二

    一.实现注册验证 package com.pb.entity; import java.util.Date; /** * 用户实体类 * */ public class User { /** * 住址 ...

  8. 【原】UIView实现点击着重效果的解决方案

    我们知道,在IOS中UIButton UIControl都有一个默认的选中效果,即点中后会图标会变暗,移开后又恢复正常.如何让UIView UIImageView等这些普通的view也实现同样的效果呢 ...

  9. IOS之未解问题--关于IOS图像渲染CPU和GPU

    前言:先上一个图.关于UIKit底层渲染机制,这个有待以后花大把时间收集资料和学习,然后汇总,将整篇"未解问题"去除. 反思:半个月前阿里电话面试,问道一个问题图像渲染什么时候回用 ...

  10. 用Qt开发第一个Hello World程序

    配置好Qt的环境变量之后,我们才可以进行下面的通过终端来使用Qt开发这个第一个程序 因为Qt的文件路径不能有中文否则会报错,所以一般都把工程文件都建立在根目录 我们创建的Qt程序包含两个部分:1.GU ...