C#?wpf?Bitmap轉(zhuǎn)換成WriteableBitmap的方法
前言
在wpf中我們有時(shí)候需要截屏或者獲取鼠標(biāo)標(biāo)時(shí)通常拿到的是Bitmap,如果要作顯示,則需要將Bitmap轉(zhuǎn)成wpf控件兼容的圖像對(duì)象,比如轉(zhuǎn)成BitmapSource在網(wǎng)上已經(jīng)可以查到實(shí)現(xiàn)方法,這里提供一種將Bitmap轉(zhuǎn)成WriteableBitmap的方法。
一、WriteableBitmap是什么?
WriteableBitmap是一個(gè)wpf對(duì)象,在命名空間System.Windows.Media.Imaging中,是BitmapSource的子類。如下圖所示:

二、如何實(shí)現(xiàn)
1.創(chuàng)建WriteableBitmap
創(chuàng)建一個(gè)與Bitmap大小相同,像素格式兼容的WriteableBitmap。
示例如下:
WriteableBitmap wb = new WriteableBitmap(bitmap.Width, bitmap.Height, 0, 0, System.Windows.Media.PixelFormats.Bgra32, null);
2.寫入數(shù)據(jù)
調(diào)用Bitmap的LockBits獲取其內(nèi)部的圖像數(shù)據(jù),通過WritePixels的方式寫入WriteableBitmap,這樣即完成了轉(zhuǎn)換。
示例如下:
var data = bitmap.LockBits(new System.Drawing.Rectangle(new System.Drawing.Point(0, 0), bitmap.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, src.PixelFormat); wb.WritePixels(new Int32Rect(srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height), data.Scan0, data.Height * data.Stride, data.Stride, destinationX, destinationY); bitmap.UnlockBits(data);
三、完整代碼
//將Bitmap 轉(zhuǎn)換成WriteableBitmap
public static WriteableBitmap BitmapToWriteableBitmap(System.Drawing.Bitmap src)
{
var wb = CreateCompatibleWriteableBitmap(src);
System.Drawing.Imaging.PixelFormat format = src.PixelFormat;
if (wb == null)
{
wb = new WriteableBitmap(src.Width, src.Height, 0, 0, System.Windows.Media.PixelFormats.Bgra32, null);
format = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
}
BitmapCopyToWriteableBitmap(src, wb, new System.Drawing.Rectangle(0, 0, src.Width, src.Height), 0, 0, format);
return wb;
}
//創(chuàng)建尺寸和格式與Bitmap兼容的WriteableBitmap
public static WriteableBitmap CreateCompatibleWriteableBitmap(System.Drawing.Bitmap src)
{
System.Windows.Media.PixelFormat format;
switch (src.PixelFormat)
{
case System.Drawing.Imaging.PixelFormat.Format16bppRgb555:
format = System.Windows.Media.PixelFormats.Bgr555;
break;
case System.Drawing.Imaging.PixelFormat.Format16bppRgb565:
format = System.Windows.Media.PixelFormats.Bgr565;
break;
case System.Drawing.Imaging.PixelFormat.Format24bppRgb:
format = System.Windows.Media.PixelFormats.Bgr24;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppRgb:
format = System.Windows.Media.PixelFormats.Bgr32;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppPArgb:
format = System.Windows.Media.PixelFormats.Pbgra32;
break;
case System.Drawing.Imaging.PixelFormat.Format32bppArgb:
format = System.Windows.Media.PixelFormats.Bgra32;
break;
default:
return null;
}
return new WriteableBitmap(src.Width, src.Height, 0, 0, format, null);
}
//將Bitmap數(shù)據(jù)寫入WriteableBitmap中
public static void BitmapCopyToWriteableBitmap(System.Drawing.Bitmap src, WriteableBitmap dst, System.Drawing.Rectangle srcRect, int destinationX, int destinationY, System.Drawing.Imaging.PixelFormat srcPixelFormat)
{
var data = src.LockBits(new System.Drawing.Rectangle(new System.Drawing.Point(0, 0), src.Size), System.Drawing.Imaging.ImageLockMode.ReadOnly, srcPixelFormat);
dst.WritePixels(new Int32Rect(srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height), data.Scan0, data.Height * data.Stride, data.Stride, destinationX, destinationY);
src.UnlockBits(data);
}四、使用示例
1.直接轉(zhuǎn)換
//創(chuàng)建一個(gè)Bitmap對(duì)象 var bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); //繪制Bitmap //略 //繪制Bitmap--end //將Bitmap轉(zhuǎn)換為WriteableBitmap var wb=BitmapToWriteableBitmap(bitmap);
2.復(fù)用寫入
//創(chuàng)建一個(gè)Bitmap對(duì)象
var bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
//創(chuàng)建格式兼容的WriteableBitmap
var wb = CreateCompatibleWriteableBitmap(bitmap);
System.Drawing.Imaging.PixelFormat format = bitmap .PixelFormat;
if (wb == null)
//格式不兼容則強(qiáng)制使用bgr32
{
wb = new WriteableBitmap(bitmap .Width, bitmap .Height, 0, 0, System.Windows.Media.PixelFormats.Bgra32, null);
format = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
}
while (true)
{
//繪制Bitmap
//略
//繪制Bitmap--end
//將Bitmap數(shù)據(jù)寫入WriteableBitmap
BitmapCopyToWriteableBitmap(bitmap, wb, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, format);
}總結(jié)
以上就是今天要講的內(nèi)容,本質(zhì)上就是對(duì)圖像數(shù)據(jù)的直接拷貝,剛好Bitmap有獲取內(nèi)部數(shù)據(jù)的接口,而WriteableBitmap也剛好有寫入數(shù)據(jù)的接口。這種方法避免了新的句柄產(chǎn)生,不會(huì)出現(xiàn)內(nèi)存泄漏。而且直接的數(shù)據(jù)拷貝,不需要編解碼,性能是非常好的。
到此這篇關(guān)于C# wpf Bitmap轉(zhuǎn)換成WriteableBitmap的方法的文章就介紹到這了,更多相關(guān)C# Bitmap轉(zhuǎn)換成WriteableBitmap內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
WPF自定義TreeView控件樣式實(shí)現(xiàn)QQ聯(lián)系人列表效果
TreeView控件在項(xiàng)目中使用比較頻繁,下面這篇文章主要給大家介紹了關(guān)于WPF自定義TreeView控件樣式實(shí)現(xiàn)QQ聯(lián)系人列表效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2018-04-04
C#連接SQL Server的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于C#連接SQL Server的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
C#使用表達(dá)式樹(LambdaExpression)動(dòng)態(tài)更新類的屬性值(示例代碼)
這篇文章主要介紹了C#使用表達(dá)式樹(LambdaExpression)動(dòng)態(tài)更新類的屬性值,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01
Unity?百度AI實(shí)現(xiàn)Logo商標(biāo)識(shí)別
本文主要介紹了Unity實(shí)現(xiàn)檢測(cè)和識(shí)別圖片中的品牌LOGO信息。即對(duì)于輸入的一張圖片(可正常解碼,且長寬比適宜),輸出圖片中LOGO的名稱、位置和置信度。需要的可以參考一下2022-01-01
C#byte數(shù)組與Image的相互轉(zhuǎn)換實(shí)例代碼
這篇文章主要介紹了C#byte數(shù)組與Image的相互轉(zhuǎn)換實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-04-04
c#遍歷System.drawing.Color下面的所有顏色以及名稱以查看
c#遍歷System.drawing.Color下面的所有顏色以及名稱以查看,需要的朋友可以參考一下2013-02-02

