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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM