GUI (work in progress..)
[master-thesis.git] / Parasitemia / Parasitemia / GUI / Pia.fs
1 // ParasitemIA file format.
2 module Parasitemia.GUI.Pia
3
4 open System.Windows
5 open System.IO
6 open System.IO.Compression
7
8 open FSharp.Data
9
10 open Emgu.CV
11 open Emgu.CV.Structure
12
13 open Types
14
15 let extension = ".pia"
16 let filter = "PIA|*.pia"
17
18 type FileData = {
19 sources: SourceImage list
20 patientID: string }
21
22 // The json type associated to a source image.
23 type JSONSourceImage = JsonProvider<"""
24 {
25 "rbcs": [
26 {
27 "num": 1,
28 "infected": true,
29 "addedManually": false,
30 "removed": false,
31 "posX" : 42.5,
32 "posY" : 42.5,
33 "width" : 10.5,
34 "height" : 10.5,
35 "stainArea" : 10
36 }
37 ]
38 }
39 """>
40
41 // The json type associated to a file.
42 type JSONMainInformation = JsonProvider<"""
43 {
44 "patientID": "1234abcd"
45 }
46 """>
47
48 let mainFilename = "info.json"
49 let imageExtension = ".tiff"
50
51 let save (filePath: string) (data: FileData) =
52 use file = ZipFile.Open(filePath, ZipArchiveMode.Update)
53
54 for e in List.ofSeq file.Entries do // 'ofSeq' to not iterate a collection currently modified.
55 e.Delete()
56
57 // Main JSON file.
58 let mainJSON = JSONMainInformation.Root(data.patientID)
59 let mainFile = file.CreateEntry(mainFilename, CompressionLevel.Fastest)
60 use mainFileWriter = new StreamWriter(mainFile.Open())
61 mainJSON.JsonValue.WriteTo(mainFileWriter, JsonSaveOptions.None)
62
63 // Write each images and the associated information.
64 for imgSrc in data.sources do
65 let imgFilename = (string imgSrc.num) + imageExtension
66 let imgEntry = file.CreateEntry(imgFilename, CompressionLevel.NoCompression) // FIXME: It seems a compression is applied to this file despite of the 'NoCompression' flag.
67 imgSrc.img.ToBitmap().Save(imgEntry.Open(), System.Drawing.Imaging.ImageFormat.Tiff)
68
69 let imgJSON =
70 JSONSourceImage.Root([| for rbc in imgSrc.rbcs ->
71 JSONSourceImage.Rbc(
72 rbc.num,
73 rbc.infected, rbc.addedManually, rbc.removed,
74 decimal rbc.center.X, decimal rbc.center.Y, decimal rbc.size.Width, decimal rbc.size.Height,
75 rbc.stainArea) |])
76
77 let imgJSONEntry = file.CreateEntry(imgFilename + ".json", CompressionLevel.Fastest)
78 use imgJSONFileWriter = new StreamWriter(imgJSONEntry.Open())
79 imgJSON.JsonValue.WriteTo(imgJSONFileWriter, JsonSaveOptions.None)
80
81
82 let load (filePath: string) : FileData =
83 use file = ZipFile.Open(filePath, ZipArchiveMode.Read)
84
85 let mainFile = file.GetEntry(mainFilename)
86 let mainJSON = JSONMainInformation.Load(mainFile.Open())
87
88 let sources = [
89 let mutable imgNum = 0
90 for imgEntry in file.Entries do
91 let filename = imgEntry.Name
92 if filename.EndsWith(imageExtension)
93 then
94 let img = new Image<Bgr, byte>(new System.Drawing.Bitmap(imgEntry.Open(), false)) // FIXME: Should we dispose the bitmap?
95 imgNum <- imgNum + 1
96 let imgJSONEntry = file.GetEntry(filename + ".json")
97 let imgJSON = JSONSourceImage.Load(imgJSONEntry.Open())
98 yield { num = imgNum; img = img; rbcs = [ for rbc in imgJSON.Rbcs ->
99 { num = rbc.Num;
100 infected = rbc.Infected; addedManually = rbc.AddedManually; removed = rbc.Removed;
101 center = Point(float rbc.PosX, float rbc.PosY); size = Size(float rbc.Width, float rbc.Height);
102 stainArea = rbc.StainArea } ] } ]
103 { sources = sources; patientID = mainJSON.PatientId }