SharpDX之Direct2D教程II——加载位图文件和保存位图文件

简介:

本系列文章目录:

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  IntegerAs 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  StringOptional 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  IntegerAs 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))); 
        } 
    } 
}

    本文转自万仓一黍博客园博客,原文链接:http://www.cnblogs.com/grenet/p/3330440.html,如需转载请自行联系原作者


相关文章
|
7月前
|
XML 存储 JSON
使用自定义XML配置文件在.NET桌面程序中保存设置
本文将详细介绍如何在.NET桌面程序中使用自定义的XML配置文件来保存和读取设置。除了XML之外,我们还将探讨其他常见的配置文件格式,如JSON、INI和YAML,以及它们的优缺点和相关的NuGet类库。最后,我们将重点介绍我们为何选择XML作为配置文件格式,并展示一个实用的示例。
96 0
|
1天前
|
存储 Linux Android开发
Rockchip u-boot阶段命令行和代码方式读取u盘内容并解析
Rockchip u-boot阶段命令行和代码方式读取u盘内容并解析
6 2
|
2月前
MFC编程 -- 保存和读取列表框内容
MFC编程 -- 保存和读取列表框内容
18 0
|
Web App开发 缓存 网络协议
Mac 调整启动台 LaunchPad 的图标以及清空DNS缓存
Mac 调整启动台 LaunchPad 的图标以及清空DNS缓存
291 0
|
监控 NoSQL Redis
持久化-save配置与工作原理|学习笔记
快速学习持久化-save配置与工作原理
66 0
持久化-save配置与工作原理|学习笔记
|
存储 JSON 分布式计算
Spark的数据读取与保存之文件类数据读取与保存
Spark的数据读取与保存之文件类数据读取与保存
610 0
|
存储 分布式计算 Hadoop
Spark的数据读取与保存之文件系统类数据读取与保存
Spark的数据读取与保存之文件系统类数据读取与保存
293 0
实例演示相机的OnImageRender和Clear Flags清理标识(Unity3D)
无论多基础、简单的知识,只要不会,就是难。。 这次的总结主要与相机上的Clear Flags及OnImageRender函数有关Clear Flags对于这个选项,我是这么理解的:每一个相机在开始绘制时,都需要对当前RenderBuffer中的颜色缓冲区(ColorBuffer)和深度缓冲区(Z-Buffer)进行是否清除的操作,这个选项控制了清除及清除后的内容。
|
机器学习/深度学习 TensorFlow 算法框架/工具
模型保存与加载|学习笔记
快速学习模型保存与加载
|
XML Android开发 数据格式
【PageLayout】非常简单的一键切换加载-空数据-错误页,支持自定义
版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/82594706 项目中我们经常会用到的加载数据,加载完数据后显示内容,如果没有数据显示一个空白页,这是如果网络错误了显示一个网络错误页,自定义一个PageLayout。
1128 0

热门文章

最新文章