本系列文章目錄:
<a href="http://www.cnblogs.com/grenet/p/3329567.html" target="_blank">SharpDX之Direct2D教程I——簡單示例和Color(顔色)</a>
繪制位圖是繪制操作的不可缺少的一部分。在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
下面是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)
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 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 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);
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,如需轉載請自行聯系原作者