Skip to content

Instantly share code, notes, and snippets.

@chikatoike
Created July 28, 2013 04:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chikatoike/6097459 to your computer and use it in GitHub Desktop.
Save chikatoike/6097459 to your computer and use it in GitHub Desktop.
FloodFill (WIP)
open System
open System.Windows
open System.Windows.Controls
open System.Windows.Media.Imaging
open System.Windows.Media.Effects
open System.Diagnostics
open System.Collections.Generic
let fillBmp pixels color =
Array.fill pixels 0 pixels.Length color
let distance x1 y1 x2 y2 =
// Math.Sqrt ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
let a = (x1 - x2) * (x1 - x2)
let b = (y1 - y2) * (y1 - y2)
Math.Sqrt ((float a) + (float b))
let putPoint (pixels : int[]) width height px py =
for y = 0 to height - 1 do
for x = 0 to width - 1 do
if (distance x y px py) < 10.0 then
pixels.[x + y * width] <- 0xff
let floodFill (pixels : int[]) width height px py color =
let region_map : byte[,] = Array2D.zeroCreate width height
let regionid = 1uy
region_map.[px, py] <- regionid
let key = pixels.[px + py * width]
let xdelt = [| -1; 1; 0; 0; |]
let ydelt = [| 0; 0; -1; 1; |]
let queue = new Queue<int * int>()
queue.Enqueue(px, py)
while queue.Count > 0 do
let x, y = queue.Dequeue()
for i = 0 to 3 do
let cx = x + xdelt.[i]
let cy = y + ydelt.[i]
if 0 <= cx && cx < width && 0 <= cy && cy < height then
if region_map.[cx, cy] <> regionid then
if pixels.[cx + cy * width] = key then
region_map.[cx, cy] <- regionid
queue.Enqueue(cx, cy)
for y = 0 to height - 1 do
for x = 0 to width - 1 do
if region_map.[x, y] = regionid then
pixels.[x + y * width] <- color
()
let w = new Window(Title = "title", Width = 1000., Height = 873. + 24.)
w.Loaded.Add(fun _ ->
let img = new Image()
let bmp = new BitmapImage(new Uri(@"..\..\25897778_p2.jpg", UriKind.Relative))
img.Source <- bmp
// img.Stretch <- Media.Stretch.None
// Trace.WriteLine((sprintf "img:%f, %f" img.Width, img.Height))
w.Content <- img
let wbmp = new WriteableBitmap(bmp)
let width = wbmp.PixelWidth
let stride = wbmp.PixelWidth * wbmp.Format.BitsPerPixel / 8
let pixels = Array.zeroCreate<int> (stride * wbmp.PixelHeight) // pixel format: ARGB
wbmp.CopyPixels(pixels, stride, 0)
img.MouseDown.Add(fun (e : Input.MouseButtonEventArgs) ->
let x = e.GetPosition(null).X / img.ActualWidth * float(bmp.PixelWidth) |> int
let y = e.GetPosition(null).Y / img.ActualHeight * float(bmp.PixelHeight) |> int
Trace.WriteLine(sprintf "img.MouseDown %A" (e.GetPosition(null)))
Trace.WriteLine(sprintf "x = %d y = %d" x y)
if wbmp.Format.BitsPerPixel = 32 then
// putPoint pixels bmp.PixelWidth bmp.PixelHeight x y
floodFill pixels bmp.PixelWidth bmp.PixelHeight x y 0xff
// for y = 0 to bmp.PixelHeight - 1 do
// for x = 0 to wbmp.PixelWidth - 1 do
// pixels.[x + y * width] <- 0xff
wbmp.WritePixels(new Int32Rect(0, 0, wbmp.PixelWidth, wbmp.PixelHeight), pixels, stride, 0)
img.Source <- wbmp
)
)
[<EntryPoint>][<STAThread>]
let main _ = (Application()).Run w
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment