Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created October 4, 2017 10:43
Show Gist options
  • Save hodzanassredin/a48b95d763ea327a6e04129447fb034d to your computer and use it in GitHub Desktop.
Save hodzanassredin/a48b95d763ea327a6e04129447fb034d to your computer and use it in GitHub Desktop.
image linear trnsformations
#r "System.Drawing.dll"
module Bitmap =
open System
open System.IO
open System.Drawing
open System.Drawing.Imaging
let toArray (image:Bitmap) =
Array2D.init image.Width image.Height (fun i j -> image.GetPixel(i,j))
type DynamicImage = (int*int*Color)[]
let dynamicToArray (image : DynamicImage) =
let minX = image |> Array.map (fun (x,_,_) -> x) |> Array.min
let maxX = image |> Array.map (fun (x,_,_) -> x) |> Array.max
let minY = image |> Array.map (fun (_,y,_) -> y) |> Array.min
let maxY = image |> Array.map (fun (_,y,_) -> y) |> Array.max
let lenX = maxX - minX + 1
let lenY = maxY - minY + 1
printfn "out size %d %d" lenX lenY
let res = Array2D.zeroCreate lenX lenY
for (x,y,c) in image do
let x = x - minX
let y = y - minY
//printfn "set %d %d" x y
res.[x, y] <- c
res
let fromArray (arr : Color[,]) =
let w,h = Array2D.length1 arr, Array2D.length2 arr
let res = new Bitmap (w,h)
Array2D.iteri (fun i j c -> res.SetPixel(i,j,c)) arr
res
let load path : Bitmap = downcast Image.FromFile(path, true)
let save path (image : Bitmap) = image.Save path
module Transformations =
type Transformation = float[,]
type Vector = float[]
let apply (trans:Transformation) (v:Vector) =
let res = Array.create (Array2D.length1 trans) 0.0
for j in 0..(Array2D.length1 trans - 1) do
for i in 0..(v.Length - 1) do
res.[j] <- res.[j] + trans.[j,i] * v.[i]
res
open Transformations
open Bitmap
let transformImage (trans:Transformation) step img =
let arr = img |> toArray
let res = ResizeArray()
for i in 0.0..step..(float(Array2D.length1 arr - 1)) do
for j in 0.0..step..(float(Array2D.length2 arr - 1)) do
let [|x;y|] = apply trans [|float i;float j|]
res.Add(int x, int y, arr.[int i,int j])
res.ToArray() |> dynamicToArray |> fromArray
let transformFile (trans:Transformation) step inImagePath outImagePath =
let res = load inImagePath |> transformImage trans step
save outImagePath res
//apply (array2D [|[|2.0;1.0|];[|0.0;1.0|]|]) [|1.0;2.0|]
open System.Drawing
open System.Windows.Forms
open System.Threading
let mutable img = load "D:\\tmp\\leo.jpg"
let form = new Form(Visible = true, TopMost = true, Width = img.Width, Height = img.Height)
form.BackgroundImage <- transformImage (array2D [|[|2.0;1.0|];[|0.0;1.0|]|]) 0.1 img :> Image
form.Size = form.BackgroundImage.Size;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment