首頁 > 軟體

C# wpf Bitmap轉換成WriteableBitmap的方法

2022-08-04 22:06:36

前言

在wpf中我們有時候需要截圖或者獲取滑滑鼠時通常拿到的是Bitmap,如果要作顯示,則需要將Bitmap轉成wpf控制元件相容的影象物件,比如轉成BitmapSource在網上已經可以查到實現方法,這裡提供一種將Bitmap轉成WriteableBitmap的方法。

一、WriteableBitmap是什麼?

WriteableBitmap是一個wpf物件,在名稱空間System.Windows.Media.Imaging中,是BitmapSource的子類。如下圖所示:

二、如何實現

1.建立WriteableBitmap

建立一個與Bitmap大小相同,畫素格式相容的WriteableBitmap。
範例如下:

WriteableBitmap wb = new WriteableBitmap(bitmap.Width, bitmap.Height, 0, 0, System.Windows.Media.PixelFormats.Bgra32, null);

2.寫入資料

呼叫Bitmap的LockBits獲取其內部的影象資料,通過WritePixels的方式寫入WriteableBitmap,這樣即完成了轉換。

範例如下:

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 轉換成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;
}
//建立尺寸和格式與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資料寫入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.直接轉換

//建立一個Bitmap物件
var bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
//繪製Bitmap
//略
//繪製Bitmap--end
//將Bitmap轉換為WriteableBitmap
var wb=BitmapToWriteableBitmap(bitmap);

2.複用寫入

//建立一個Bitmap物件
var bitmap = new System.Drawing.Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
//建立格式相容的WriteableBitmap
var wb = CreateCompatibleWriteableBitmap(bitmap);
System.Drawing.Imaging.PixelFormat format = bitmap .PixelFormat;
if (wb == null)
//格式不相容則強制使用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資料寫入WriteableBitmap
    BitmapCopyToWriteableBitmap(bitmap, wb, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, format);
}

總結

以上就是今天要講的內容,本質上就是對影象資料的直接拷貝,剛好Bitmap有獲取內部資料的介面,而WriteableBitmap也剛好有寫入資料的介面。這種方法避免了新的控制程式碼產生,不會出現記憶體漏失。而且直接的資料拷貝,不需要編解碼,效能是非常好的。

到此這篇關於C# wpf Bitmap轉換成WriteableBitmap的方法的文章就介紹到這了,更多相關C# Bitmap轉換成WriteableBitmap內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com