X-Git-Url: http://git.euphorik.ch/?p=master-thesis.git;a=blobdiff_plain;f=Parasitemia%2FParasitemiaUI%2FPiaZ.fs;fp=Parasitemia%2FParasitemiaUI%2FPiaZ.fs;h=d4ea46fa6eb062492bc5b1624e9555f68dd4ebb8;hp=0000000000000000000000000000000000000000;hb=4bfa3cbdc6145e6944f02e24829ab2ef3a851ac1;hpb=48ecdfc43001c444eff6ad442986049384674af2 diff --git a/Parasitemia/ParasitemiaUI/PiaZ.fs b/Parasitemia/ParasitemiaUI/PiaZ.fs new file mode 100644 index 0000000..d4ea46f --- /dev/null +++ b/Parasitemia/ParasitemiaUI/PiaZ.fs @@ -0,0 +1,97 @@ +// ParasitemIA Zipped document format. +module ParasitemiaUI.PiaZ + +open System +open System.Windows +open System.IO +open System.IO.Compression + +open Emgu.CV +open Emgu.CV.Structure + +open Newtonsoft.Json +open Newtonsoft.Json.Converters + +open Types + +let extension = ".piaz" +let filter = "PIA|*.piaz" + +// Information associated to a document. +type JSONInformation = { + patientID: string +} + +// Information associated to each images. +type JSONSourceImage = { + num: int + RBCRadius: float32 // The RBC Radius found by granulometry. + parameters: ParasitemiaCore.Config.Parameters + dateLastAnalysis: DateTime + rbcs: RBC List +} + +type DocumentData = { + patientID: string + images: SourceImage list +} + +let mainEntryName = "info.json" +let imageExtension = ".tiff" + +/// +/// Save a document in a give file path. The file may already exist. +/// +/// +/// +/// If the file cannot be written +let save (filePath: string) (data: DocumentData) = + use file = ZipFile.Open(filePath, ZipArchiveMode.Update) + + for e in List.ofSeq file.Entries do // 'ofSeq' to not iterate a collection currently modified. + e.Delete() + + // Main JSON file. + let mainEntry = file.CreateEntry(mainEntryName, CompressionLevel.Fastest) + use mainEntryWriter = new StreamWriter(mainEntry.Open()) + mainEntryWriter.Write(JsonConvert.SerializeObject({ JSONInformation.patientID = data.patientID })) + + // Write each images and the associated information. + for srcImg in data.images do + let imgFilename = (string srcImg.num) + imageExtension + let imgEntry = file.CreateEntry(imgFilename, CompressionLevel.NoCompression) // FIXME: It seems a compression is applied to this file despite of the 'NoCompression' flag. + srcImg.img.ToBitmap().Save(imgEntry.Open(), System.Drawing.Imaging.ImageFormat.Tiff) + + let imgJSONEntry = file.CreateEntry(imgFilename + ".json", CompressionLevel.Fastest) + use imgJSONFileWriter = new StreamWriter(imgJSONEntry.Open()) + imgJSONFileWriter.Write(JsonConvert.SerializeObject({ num = srcImg.num; RBCRadius = srcImg.config.RBCRadius.Pixel; parameters = srcImg.config.Parameters; dateLastAnalysis = srcImg.dateLastAnalysis; rbcs = srcImg.rbcs })) + +/// +/// Load document from a give file path. +/// +/// +/// If the file cannot be read +let load (filePath: string) : DocumentData = + use file = ZipFile.Open(filePath, ZipArchiveMode.Read) + + let mainEntry = file.GetEntry(mainEntryName) + use mainEntryReader = new StreamReader(mainEntry.Open()) + let info = JsonConvert.DeserializeObject(mainEntryReader.ReadToEnd()) + + { patientID = info.patientID + images = [ let mutable imgNum = 0 + for imgEntry in file.Entries do + if imgEntry.Name.EndsWith(imageExtension) + then + let img = new Image(new System.Drawing.Bitmap(imgEntry.Open(), false)) // FIXME: Should we dispose the bitmap? + imgNum <- imgNum + 1 + let imgEntry = file.GetEntry(imgEntry.Name + ".json") + use imgEntryFileReader = new StreamReader(imgEntry.Open()) + let imgInfo = JsonConvert.DeserializeObject(imgEntryFileReader.ReadToEnd()) + let config = ParasitemiaCore.Config.Config(imgInfo.parameters) + config.SetRBCRadius imgInfo.RBCRadius + yield { num = imgNum + config = config + dateLastAnalysis = imgInfo.dateLastAnalysis + img = img + rbcs = imgInfo.rbcs } ] } \ No newline at end of file