標籤:visual ima sys image 功能 win 操作 代碼提示 invalid
堅持寫部落格是最近的目標。加油。
業餘學習fsharp以來一直覺得這才是Dotnet開發,或者說所有開發人員應該擁有的語言。配合Visual Studio的代碼提示,即時執行視窗。開發程式有著極大的樂趣。
最近想學習一些影像處理的相關知識。試著把Fsharp又撿了起來。邊學邊玩,希望兩個方面都有所進益。
映像的處理首先要解決顯示的問題。在FSI中內嵌了Winform的訊息處理,可以很方便的幾句話畫出一個帶PictureBox的表單。在FSI中由於可以保持對表單和控制項的控制權,當更新演算法後,我們可以很快的看到結果。擁有即時反饋的編程工具真是開發人員的幸運。
open System.Windows.Formslet form = new Form()let image = new PictureBox(Dock = DockStyle.Fill)form.Controls.Add(image)image.SizeMode <- PictureBoxSizeMode.StretchImageform.Show()
顯示表單的代碼如上所示,非常的簡單。當然此時什麼都沒有。下面來載入一張圖片
open System.Drawinglet image_path = __SOURCE_DIRECTORY__ + @"\Chrysanthemum.jpg"let bitmap = new Bitmap(image_path)image.Image <- bitmap
好了最基本的架構完成了。此時我們仍可以通過bitmap,image等變數控制視窗的顯示。
最後是反色程式,首先我們取出所有像素點
let Pixels =seq {for h in 0..bitmap.Height-1 do for w in 0..bitmap.Width-1 do yield bitmap.GetPixel(w, h)}
進行反色操作
Pixels |> Seq.iteri(fun i c -> bitmap.SetPixel(i%bitmap.Width, i/bitmap.Width, Color.FromArgb((255 - (int c.R)), (255 - (int c.G)), (255 - (int c.B)))))//win10 seem to need to update manuallyimage.Invalidate()
很簡單吧。就是速度哦有些慢。主要是SetPixel和GetPixel操作拖累了速度。
使用BitmapData可以大大加快速度。使用#time 操作開啟操作時間顯示看看快了多少
let imagerect = new Rectangle(0,0,bitmap.Width, bitmap.Height)let bitmapdata = bitmap.LockBits(imagerect, ImageLockMode.ReadWrite, bitmap.PixelFormat)let buffer:byte[] = Array.zeroCreate (bitmap.Width * bitmap.Height * Bitmap.GetPixelFormatSize(bitmap.PixelFormat)/8)Marshal.Copy(bitmapdata.Scan0, buffer, 0, buffer.Length)let newbuff = buffer |> Seq.map(fun x -> 255uy - x) |> Array.ofSeqMarshal.Copy(newbuff, 0, bitmapdata.Scan0, buffer.Length)bitmap.UnlockBits(bitmapdata)image.Invalidate()
Real: 00:00:01.227,CPU: 00:00:01.218,GC gen0: 0, gen1: 0, gen2: 0Real: 00:00:00.050,CPU: 00:00:00.046,GC gen0: 0, gen1: 0, gen2: 0
下次再找個知識點,不過似乎要先補補微積分和線代了。
使用FSharp 探索Dotnet影像處理功能1--反色變化