在WPF中編輯圖片的像素

來源:互聯網
上載者:User

【提示:為了方便大家閱讀並尋求參考,文中的超連結均串連到MSDN中的相應內容。】

前些天開始研究WPF。是從圖片的顯示、編輯和儲存開始研究的。

在我看來,WPF和以前的Form在圖片處理方面的變化太大了。它們分別用了不同的類來表示圖片。在From中用的是Image類;而在WPF中,Image已經作為顯示圖片用的控制項了,表示圖片的類是ImageSourceBitmapSourceBitmapImage、 WriteableBitmap等。現在還不是很清楚這些類的特點和具體應用方面。

不過前些天遇到的問題(http://student.csdn.net/space.php?uid=127131&do=thread&id=10182)也算是通過努力解決了。

現在就總結一下:

1、首先要瞭解圖片的格式。

我所用的源圖片都是jpg或bmp格式的。在這兩種格式圖片中一般都是用R、G、B三個元素表示一個像素。所以在程式中每個像素都是用3個byte型的變數表示的。

這裡面還應該說一下。當對圖片進行像素的讀取操作時,圖片的Width和height應該用PixelWidth和PixelHeight屬性擷取。因為在WPF中Width和height屬性是double型的,它用來表示映像的顯示尺寸,而不是實際尺寸。

2、讀入並用Image控制項顯示圖片。

在WPF中,感覺檔案的路徑好多都要轉化成Uri類的對象才能很方便地使用。要讀片當然利用OpenFileDialog先找到圖片的路徑fileName(當然是string型的)。然後建立一個Uri fileUri=new Uri(fileName);。之後,我利用BitmapDecoder類將圖片解碼,並將解碼後的圖片送到Image控制項中顯示。至於Create中的後兩個參數我也不是很明白,只知道這樣做沒有錯。

Code:
  1. Uri fileUri=new Uri(fileName);  
  2. BitmapDecoder decoder = BitmapDecoder.Create(fileUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);  
  3. image1.Source = decoder.Frames[0];  


3、其次要找到方法將圖片的像素讀出來,並將修改後的像素寫回去。

在以上提到的WPF中表示圖片的四個類中,BitmapSource、BitmapImage、 WriteableBitmap都具有CopyPixels方法。用這個方法就可以將映像中的像素讀出來。其原型為public virtual void CopyPixels(Array pixels,int stride, int offset)【這裡只介紹這一種重載方式】。

Array pixels:執行此函數後,這個變數裡面的值就是所要取得的圖片像素資料。在調用這個函數之前可以先聲明一個byte型數組(如byte[] imgPixels = new byte[像素個數×每個像素所含元素個數]);

int stride:stride原意為跨越、步幅。經過我分析,感覺它在這裡表示圖片的一行所需要的byte數量。也就是【每行像素個數×每個像素元素個數】;

int offset:這個比較好理解,就是從哪裡(用像素表示的位置)開始copy pixels。

4、對像素資料(imgPixels 數組)進行操作。

這裡我就不說了,您隨意!

5、用修改後的資料產生新的映像。

上面說擷取像素時,BitmapSource、BitmapImage、 WriteableBitmap都可以,但是利用像素產生圖片時,卻只有WriteableBitmap才能勝任。因為只有它才具有WritePixels方法。其原型為public void WritePixels(Int32Rect sourceRect,Array pixels,int stride,int offset)【這裡只介紹這一種重載方式】。

Int32Rect sourceRect:需要更新的地區,也就是需要用像素資料更改的地區。如果建立一張新圖片的話,那這裡就是new Int32Rect(0,0,PixelWidth,PixelHeight)了;

Array pixels和int stride就不多解釋了,含義和用法同上;

int offset:還是有必要說一下的。在這裡,它指的是像素資料的位移量,也就是pixels數組的位移量,而不是像素的位移量。

這裡面,WriteableBitmap類型的圖片可以很方便轉換成其他幾種圖片類型。

6、儲存剛剛產生的圖片。

由於我是對像素進行的操作,並向讓再次開啟圖片是能夠知道我對象度進行了哪些操作,所以我將映像儲存成Bmp格式。這裡面的重點是要用BitmapEncoder類將映像編碼。當然不同映像格式有不同的類繼承自BitmapEncoder類,向這裡就用到了BitmapEncoder類的子類BmpBitmapEncoder。不多解釋了,代碼如下:

Code:
  1. static public void SaveImage(string file, BitmapSource img)  
  2.  {  
  3.       BmpBitmapEncoder encoder = new BmpBitmapEncoder();  
  4.       encoder.Frames.Add(BitmapFrame.Create(img));  
  5.   
  6.       FileStream bitmap = new FileStream(file, FileMode.Create, FileAccess.Write);  
  7.       encoder.Save(bitmap);  
  8.       bitmap.Close();  
  9.  }  

就這樣,有興趣的可以試一試。

另外我初學WPF,有什麼說的不對的,還請大家協助批評指導啊!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.