1
// ParasitemIA Zipped document format.
2 module ParasitemiaUI.PiaZ
6 open System.IO.Compression
15 let extension = ".piaz"
16 let filter = "PIA|*.piaz"
18 // Information associated to a document.
19 type JSONInformation =
25 // Information associated to each images.
26 type JSONSourceImage =
31 RBCRadius : float32
// The RBC Radius found by granulometry.
32 parameters
: ParasitemiaCore.Config.Parameters
33 dateLastAnalysis
: DateTime
36 healthyRBCBrightness
: float32
// 0 to 1.
37 infectedRBCBrightness
: float32
// 0 to 1.
43 images
: SourceImage list
46 let MAIN_ENTRY_NAME = "info.json"
47 let DEFAULT_IMAGE_EXTENSION = ".tiff"
48 let JSON_EXTENSION = ".json"
49 let CURRENT_FILE_VERSION = 3
52 /// Save a document in a give file path. The file may already exist.
54 /// <param name="filePath"></param>
55 /// <param name="data"></param>
56 /// <exception cref="System.IOException">If the file cannot be written</exception>
57 let save (filePath
: string) (data
: DocumentData) =
58 use file = ZipFile.Open (filePath
, ZipArchiveMode.Update)
60 // We only delete JSON files and removed images.
61 for e
in List.ofSeq
file.Entries do // 'ofSeq' to not iterate a collection currently modified.
62 if Path.GetExtension e
.Name = JSON_EXTENSION || data.images
|> List.exists
(fun img
-> img
.OriginalName = e
.Name) |> not
then
66 let mainEntry = file.CreateEntry (MAIN_ENTRY_NAME, CompressionLevel.Fastest)
67 use mainEntryWriter = new StreamWriter (mainEntry.Open ())
68 mainEntryWriter.Write (JsonConvert.SerializeObject ({ patientID
= data.patientID
; fileVersion
= CURRENT_FILE_VERSION }))
70 // Write each images and the associated information as a JSON file.
71 for srcImg
in data.images
do
72 match srcImg
.TempFile with
74 let imgEntry = file.CreateEntry (srcImg
.OriginalName, CompressionLevel.NoCompression)
75 (File.Open (imgTempFile
, FileMode.Open, FileAccess.Read)).CopyTo (imgEntry.Open ())
76 srcImg
.TempFile <- None
80 //let imgFilename = (string srcImg.Num) + DEFAULT_IMAGE_EXTENSION
81 //let imgEntry = file.CreateEntry (imgFilename, CompressionLevel.NoCompression)
82 //srcImg.Img.ToBitmap().Save (imgEntry.Open (), System.Drawing.Imaging.ImageFormat.Tiff)
84 let imgJSONEntry = file.CreateEntry (srcImg
.OriginalName + JSON_EXTENSION, CompressionLevel.Fastest)
85 use imgJSONFileWriter = new StreamWriter (imgJSONEntry.Open ())
86 imgJSONFileWriter.Write (
87 JsonConvert.SerializeObject (
91 RBCRadius = srcImg
.Config.RBCRadius.Pixel
92 parameters
= srcImg
.Config.Parameters
93 dateLastAnalysis
= srcImg
.DateLastAnalysis
95 healthyRBCBrightness
= srcImg
.HealthyRBCBrightness
96 infectedRBCBrightness
= srcImg
.InfectedRBCBrightness
101 let updateDocumentData (fromVersion
: int) (toVersion
: int) (data : DocumentData) : DocumentData =
102 for v
in fromVersion
+ 1 .. toVersion
do
104 | 1 -> // Version 0 -> 1 : set initial brightness for rbc.
105 data.images
|> List.iter
(fun i
-> i
.HealthyRBCBrightness <- 1.f
; i
.InfectedRBCBrightness <- 1.f
)
109 exception VersionFileNewerException of int
112 /// Load document from a give file path.
114 /// <param name="filePath">Path to the PiaZ file</param>
115 /// <param name="defaultConfig"></param>
116 /// <exception cref="System.IOException">If the file cannot be read</exception>
117 /// <exception cref="VersionFileNewerException">If the file version is newer than the current supported version</exception>
118 let load (filePath
: string) (defaultConfig
: ParasitemiaCore.Config.Config) : DocumentData =
119 use file = ZipFile.Open (filePath
, ZipArchiveMode.Read)
121 let mainEntry = file.GetEntry (MAIN_ENTRY_NAME)
122 use mainEntryReader = new StreamReader (mainEntry.Open ())
123 let info = JsonConvert.DeserializeObject<JSONInformation> (mainEntryReader.ReadToEnd ())
125 if info.fileVersion
> CURRENT_FILE_VERSION then
126 raise
<| VersionFileNewerException info.fileVersion
128 updateDocumentData info.fileVersion
CURRENT_FILE_VERSION
130 patientID
= info.patientID
133 for imgEntry in file.Entries do
134 if imgEntry.Name.EndsWith JSON_EXTENSION |> not
then
135 use bitmap = new System.Drawing.Bitmap (imgEntry.Open (), false)
136 let img = bitmap.ToImage<Bgr, byte
> ()
137 let imgJSONEntry = file.GetEntry (imgEntry.Name + JSON_EXTENSION)
138 use imgJSONFileReader = new StreamReader (imgJSONEntry.Open ())
139 let imgInfo = JsonConvert.DeserializeObject<JSONSourceImage> (imgJSONFileReader.ReadToEnd ())
140 let imgNum = imgInfo.num
142 let config = defaultConfig
.Copy ()
145 ParasitemiaCore.Config.defaultParameters
with
146 resolution
= imgInfo.parameters
.resolution
149 config.SetRBCRadius imgInfo.RBCRadius
151 SourceImage (imgNum, imgInfo.name
, imgEntry.Name, config, imgInfo.dateLastAnalysis
, FromMemory img, imgInfo.rbcs
, HealthyRBCBrightness = imgInfo.healthyRBCBrightness
, InfectedRBCBrightness = imgInfo.infectedRBCBrightness
)
153 |> List.sortBy
(fun image
-> image
.Num)