X-Git-Url: http://git.euphorik.ch/?p=master-thesis.git;a=blobdiff_plain;f=Parasitemia%2FParasitemiaUI%2FPiaZ.fs;h=8498c64c0a3b7e7243c2947aade5e817ccb006b4;hp=c9dfd5b8247d4022dfd1dcd810c38d1516654dec;hb=HEAD;hpb=cb90b01c85183b2c75ee6d22b378b3ca99df6bf3 diff --git a/Parasitemia/ParasitemiaUI/PiaZ.fs b/Parasitemia/ParasitemiaUI/PiaZ.fs index c9dfd5b..8498c64 100644 --- a/Parasitemia/ParasitemiaUI/PiaZ.fs +++ b/Parasitemia/ParasitemiaUI/PiaZ.fs @@ -2,7 +2,6 @@ module ParasitemiaUI.PiaZ open System -open System.Windows open System.IO open System.IO.Compression @@ -10,7 +9,6 @@ open Emgu.CV open Emgu.CV.Structure open Newtonsoft.Json -open Newtonsoft.Json.Converters open Types @@ -18,31 +16,37 @@ let extension = ".piaz" let filter = "PIA|*.piaz" // Information associated to a document. -type JSONInformation = { - patientID: string - fileVersion: int -} +type JSONInformation = + { + patientID : string + fileVersion : int + } // 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 - - healthyRBCBrightness: float32 // 0 to 1. - infectedRBCBrightness: float32 // 0 to 1. -} - -type DocumentData = { - patientID: string - images: SourceImage list -} - -let mainEntryName = "info.json" -let imageExtension = ".tiff" -let currentFileVersion = 1 +type JSONSourceImage = + { + num : int + name : string + + RBCRadius : float32 // The RBC Radius found by granulometry. + parameters : ParasitemiaCore.Config.Parameters + dateLastAnalysis : DateTime + rbcs : RBC List + + healthyRBCBrightness : float32 // 0 to 1. + infectedRBCBrightness : float32 // 0 to 1. + } + +type DocumentData = + { + patientID : string + images : SourceImage list + } + +let MAIN_ENTRY_NAME = "info.json" +let DEFAULT_IMAGE_EXTENSION = ".tiff" +let JSON_EXTENSION = ".json" +let CURRENT_FILE_VERSION = 3 /// /// Save a document in a give file path. The file may already exist. @@ -50,73 +54,101 @@ let currentFileVersion = 1 /// /// /// If the file cannot be written -let save (filePath: string) (data: DocumentData) = - use file = ZipFile.Open(filePath, ZipArchiveMode.Update) +let save (filePath : string) (data : DocumentData) = + use file = ZipFile.Open (filePath, ZipArchiveMode.Update) + // We only delete JSON files and removed images. for e in List.ofSeq file.Entries do // 'ofSeq' to not iterate a collection currently modified. - e.Delete() + if Path.GetExtension e.Name = JSON_EXTENSION || data.images |> List.exists (fun img -> img.OriginalName = e.Name) |> not then + e.Delete () // Main JSON file. - let mainEntry = file.CreateEntry(mainEntryName, CompressionLevel.Fastest) - use mainEntryWriter = new StreamWriter(mainEntry.Open()) - mainEntryWriter.Write(JsonConvert.SerializeObject({ patientID = data.patientID; fileVersion = currentFileVersion })) + let mainEntry = file.CreateEntry (MAIN_ENTRY_NAME, CompressionLevel.Fastest) + use mainEntryWriter = new StreamWriter (mainEntry.Open ()) + mainEntryWriter.Write (JsonConvert.SerializeObject ({ patientID = data.patientID; fileVersion = CURRENT_FILE_VERSION })) - // Write each images and the associated information. + // Write each images and the associated information as a JSON file. 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 - healthyRBCBrightness = srcImg.healthyRBCBrightness - infectedRBCBrightness = srcImg.infectedRBCBrightness })) - -let updateDocumentData (fromVersion: int) (toVersion: int) (data: DocumentData) : DocumentData = + match srcImg.TempFile with + | Some imgTempFile -> + let imgEntry = file.CreateEntry (srcImg.OriginalName, CompressionLevel.NoCompression) + (File.Open (imgTempFile, FileMode.Open, FileAccess.Read)).CopyTo (imgEntry.Open ()) + srcImg.TempFile <- None + + | None -> () + + //let imgFilename = (string srcImg.Num) + DEFAULT_IMAGE_EXTENSION + //let imgEntry = file.CreateEntry (imgFilename, CompressionLevel.NoCompression) + //srcImg.Img.ToBitmap().Save (imgEntry.Open (), System.Drawing.Imaging.ImageFormat.Tiff) + + let imgJSONEntry = file.CreateEntry (srcImg.OriginalName + JSON_EXTENSION, CompressionLevel.Fastest) + use imgJSONFileWriter = new StreamWriter (imgJSONEntry.Open ()) + imgJSONFileWriter.Write ( + JsonConvert.SerializeObject ( + { + num = srcImg.Num + name = srcImg.Name + RBCRadius = srcImg.Config.RBCRadius.Pixel + parameters = srcImg.Config.Parameters + dateLastAnalysis = srcImg.DateLastAnalysis + rbcs = srcImg.RBCs + healthyRBCBrightness = srcImg.HealthyRBCBrightness + infectedRBCBrightness = srcImg.InfectedRBCBrightness + } + ) + ) + +let updateDocumentData (fromVersion : int) (toVersion : int) (data : DocumentData) : DocumentData = for v in fromVersion + 1 .. toVersion do match v with | 1 -> // Version 0 -> 1 : set initial brightness for rbc. - data.images |> List.iter (fun i -> i.healthyRBCBrightness <- 1.f; i.infectedRBCBrightness <- 1.f) + data.images |> List.iter (fun i -> i.HealthyRBCBrightness <- 1.f; i.InfectedRBCBrightness <- 1.f) | _ -> () data +exception VersionFileNewerException of int + /// /// Load document from a give file path. /// -/// +/// Path to the PiaZ file +/// /// 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()) - - updateDocumentData info.fileVersion currentFileVersion - { patientID = info.patientID - images = [ let mutable imgNum = 0 - for imgEntry in file.Entries do - if imgEntry.Name.EndsWith(imageExtension) - then - use bitmap = new System.Drawing.Bitmap(imgEntry.Open(), false) - let img = new Image(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) +/// If the file version is newer than the current supported version +let load (filePath : string) (defaultConfig : ParasitemiaCore.Config.Config) : DocumentData = + use file = ZipFile.Open (filePath, ZipArchiveMode.Read) + + let mainEntry = file.GetEntry (MAIN_ENTRY_NAME) + use mainEntryReader = new StreamReader (mainEntry.Open ()) + let info = JsonConvert.DeserializeObject (mainEntryReader.ReadToEnd ()) + + if info.fileVersion > CURRENT_FILE_VERSION then + raise <| VersionFileNewerException info.fileVersion + + updateDocumentData info.fileVersion CURRENT_FILE_VERSION + { + patientID = info.patientID + images = + [ + for imgEntry in file.Entries do + if imgEntry.Name.EndsWith JSON_EXTENSION |> not then + use bitmap = new System.Drawing.Bitmap (imgEntry.Open (), false) + let img = bitmap.ToImage () + let imgJSONEntry = file.GetEntry (imgEntry.Name + JSON_EXTENSION) + use imgJSONFileReader = new StreamReader (imgJSONEntry.Open ()) + let imgInfo = JsonConvert.DeserializeObject (imgJSONFileReader.ReadToEnd ()) + let imgNum = imgInfo.num + + let config = defaultConfig.Copy () + config.Parameters <- + { + ParasitemiaCore.Config.defaultParameters with + resolution = imgInfo.parameters.resolution + } + config.SetRBCRadius imgInfo.RBCRadius - yield { num = imgNum - config = config - dateLastAnalysis = imgInfo.dateLastAnalysis - img = img - rbcs = imgInfo.rbcs - healthyRBCBrightness = imgInfo.healthyRBCBrightness - infectedRBCBrightness = imgInfo.infectedRBCBrightness } ] } \ No newline at end of file + + SourceImage (imgNum, imgInfo.name, imgEntry.Name, config, imgInfo.dateLastAnalysis, FromMemory img, imgInfo.rbcs, HealthyRBCBrightness = imgInfo.healthyRBCBrightness, InfectedRBCBrightness = imgInfo.infectedRBCBrightness) + ] + |> List.sortBy (fun image -> image.Num) + } \ No newline at end of file