(* * Bitmap Primitives Helpers * Partly inspired by http://fssnip.net/si. *) open System.Drawing // deserialize a bitmap file let fromFile (name : string) = new Bitmap(name) // serialize a bitmap as png let toFile (name : string) (bmp: Bitmap) = bmp.Save(name, Imaging.ImageFormat.Png) |> ignore bmp // load a bitmap in array of tuples (x,y,Color) let toRgbArray (bmp : Bitmap) = [| for y in 0..bmp.Height-1 do for x in 0..bmp.Width-1 -> x,y,bmp.GetPixel(x,y) |] // builds a bitmap instance from an array of tuples let toBitmap a = let height = (a |> Array.Parallel.map (fun (x,_,_) -> x) |> Array.max) + 1 let width = (a |> Array.Parallel.map (fun (_,y,_) -> y) |> Array.max) + 1 let bmp = new Bitmap(width, height) a |> Array.Parallel.iter (fun (x,y,c) -> bmp.SetPixel(x,y,c)) bmp // converts an image to gray scale let toGrayScale a = a |> Array.Parallel.map ( fun (x,y,c : System.Drawing.Color) -> let gscale = int((float c.R * 0.3) + (float c.G * 0.59) + (float c.B * 0.11)) in x,y,Color.FromArgb(int c.A, gscale, gscale, gscale)) // randomize or R or G or B each 1 to 3 pixels let randomColorize a = let rnd = new System.Random() let next = fun() -> rnd.Next(255) let rgb = function | 0 -> fun(c : System.Drawing.Color) -> Color.FromArgb(int c.A, next(), (int c.G), (int c.B)) | 1 -> fun(c) -> Color.FromArgb(int c.A, (int c.R), next(), (int c.B)) | _ -> fun(c) -> Color.FromArgb(int c.A, (int c.R), (int c.G), next()) a |> Array.Parallel.mapi ( fun i (x,y,c : System.Drawing.Color) -> if i % rnd.Next(1,3) = 0 then x,y, rgb(rnd.Next(2))(c) else x,y,c) (* * Usage example: *) let convertImage = use newBitmap = fromFile @"C:/Temp/with-color.jpg" |> toRgbArray |> toGrayScale // or custom in memory manipulation function |> toBitmap use savedBitmap = toFile @"C:/Temp/gray-scale.png" newBitmap ()