Add a DPI calculator to help to find the correct image resolution.
[master-thesis.git] / Parasitemia / ParasitemiaUI / DPICalculator.fs
1 module ParasitemiaUI.DPICalculator
2
3 open System
4 open System.Windows
5 open System.Windows.Media
6 open System.Windows.Markup
7 open System.Windows.Shapes
8 open System.Windows.Controls
9 open System.Diagnostics
10
11 open ParasitemiaCore.UnitsOfMeasure
12 open ParasitemiaCore.Types
13
14 type SensorSize = {
15 w: float<mm>
16 h: float<mm>
17 txt: string } with
18 override this.ToString () =
19 sprintf "%g mm × %g mm%s" this.w this.h (if this.txt = "" then "" else " (" + this.txt + ")")
20
21 let showWindow (parent: Window) : int option =
22 let win = Views.DPICalculatorWindow()
23 win.Root.Owner <- parent
24 win.Root.Left <- parent.Left + parent.ActualWidth / 2. - win.Root.Width / 2.
25 win.Root.Top <- parent.Top + parent.ActualHeight / 2. - win.Root.Height / 2.
26
27 let sensorSizes = [
28 { w = 5.76<mm>; h = 4.29<mm>; txt = "1/2.5″" }
29 { w = 7.6<mm>; h = 5.7<mm>; txt = "1/1.7″" }
30 { w = 8.6<mm>; h = 6.6<mm>; txt = "2/3″" }
31 { w = 13.2<mm>; h = 8.8<mm>; txt = "1″" }
32 { w = 17.3<mm>; h = 13.<mm>; txt = "" }
33 { w = 20.7<mm>; h = 13.8<mm>; txt = "" }
34 { w = 22.2<mm>; h = 14.8<mm>; txt = "" }
35 { w = 23.6<mm>; h = 15.7<mm>; txt = "" }
36 { w = 28.7<mm>; h = 19.<mm>; txt = "" }
37 { w = 28.7<mm>; h = 19.<mm>; txt = "" } ]
38
39 for size in sensorSizes do
40 win.cmbSensorSize.Items.Add(size) |> ignore
41 win.cmbSensorSize.SelectedIndex <- 0
42
43 let resolution (w_p: float<px>) (w_mm: float<mm>) (zoom: float) : float<ppi> =
44 w_p * zoom / mmToInch w_mm
45
46 let updateCurrentResolution () =
47 let { w = w; h = h } = win.cmbSensorSize.SelectedValue :?> SensorSize
48 let ratio = h / w
49
50 let parseDouble txt errorMess = match Double.TryParse(txt) with true, value -> Success value | _ -> Fail errorMess
51
52 match result
53 { let! sensorResolution = parseDouble win.txtSensorResolution.Text "The sensor resolution is not valid"
54 let! zoom = parseDouble win.txtZoom.Text "The zoom is not valid"
55 let wPixel = 1.<px> * sqrt (sensorResolution * 1e6 / ratio)
56 return! Success (float <| resolution wPixel w zoom) } with
57 | Success res -> win.txtImageResolution.Text <- (int (res / 1000.) * 1000).ToString()
58 | Fail mess -> win.txtImageResolution.Text <- mess
59
60 win.butCancel.Click.AddHandler(fun obj args -> win.Root.DialogResult <- Nullable<bool>(false); win.Root.Close())
61 win.butOK.Click.AddHandler(fun obj args -> win.Root.DialogResult <- Nullable<bool>(true); win.Root.Close())
62
63 win.cmbSensorSize.SelectionChanged.AddHandler(fun obj arg -> updateCurrentResolution ())
64 win.txtSensorResolution.TextChanged.AddHandler(fun obj arg -> updateCurrentResolution ())
65 win.txtZoom.TextChanged.AddHandler(fun obj arg -> updateCurrentResolution ())
66
67 let result = win.Root.ShowDialog()
68 if result.HasValue && result.Value
69 then
70 match Int32.TryParse win.txtImageResolution.Text with
71 | true, res -> Some res
72 | _ -> None
73 else
74 None
75