示例#1
0
        public void ImageExtractor_ProcessAsync()
        {
            // Arrange
            var loggerFactory      = base.GetService <ILoggerFactory>();
            var fileSystemStrategy = base.GetService <IFileSystemStrategy>();
            var factory            = base.GetService <IItkImageReaderFactory>();
            var command            = new ProcessPathCommand()
            {
                SourcePath      = GetDataPath("SMIR.Brain.XX.O.CT.339203.nii"),
                DestinationPath = GetTempPath(),
                AmountPerAxis   = 10,
                AxisTypes       = new HashSet <AxisType>
                {
                    AxisType.X,
                    AxisType.Y,
                    AxisType.Z
                }
            };

            IImageExtractor extractor = new ItkImageExtractor(loggerFactory, fileSystemStrategy, factory);
            var             ct        = new CancellationToken();

            try
            {
                // Act
                var result = extractor.ProcessAsync(command, ct).Result;

                // Assert
                Assert.AreEqual(28, result.Images.Count);
            }
            finally
            {
                DeleteDirectory(command.DestinationPath);
            }
        }
示例#2
0
        public void ImageService_ProcessAsync_2(string filename)
        {
            // Arrange
            var service = GetService <IImageService>();
            var ct      = new CancellationToken();
            var command = new ProcessPathCommand()
            {
                AmountPerAxis   = 4,
                OutputSize      = 50,
                SourcePath      = GetDataPath(filename),
                DestinationPath = GetTempPath()
            };

            command.AxisTypes.Add(AxisType.Z);

            try
            {
                // Act
                var result = service.ProcessAsync(command, ct).Result;
                var json   = File.ReadAllText(Path.Combine(command.DestinationPath, result.JsonFilename));

                // Assert
                Assert.AreEqual(command.AmountPerAxis, result.Images.Count);
            }
            finally
            {
                DeleteDirectory(command.DestinationPath);
            }
        }
示例#3
0
        private async Task ExecuteCommandAsync(ProcessPathCommand command, CancellationToken ct, bool openCombinedGif = false)
        {
            var watch = Stopwatch.StartNew();

            Logger.LogInformation($"{this.GetMethodName()} started");

            var result = await Mediator.Send(command, ct);

            if (openCombinedGif)
            {
                var p = new Process
                {
                    StartInfo = new ProcessStartInfo(Path.Combine(command.DestinationPath, result.CombinedGif))
                    {
                        UseShellExecute = true
                    }
                };
                p.Start();
            }

            watch.Stop();

            TimeSpan t = TimeSpan.FromMilliseconds(watch.ElapsedMilliseconds);

            Logger.LogInformation($"{this.GetMethodName()} ended after {t.ToReadableTime()}");
        }
示例#4
0
        public async Task ExecuteAsync(string[] args, CancellationToken ct)
        {
            var  command         = new ProcessPathCommand();
            bool openCombinedGif = false;

            Parser.Default.ParseArguments <Options>(args)
            .WithParsed(o =>
            {
                command.OutputSize      = o.OutputSize;
                command.AmountPerAxis   = o.AmountPerAxis;
                command.SourcePath      = o.SourcePath;
                command.DestinationPath = o.DestinationPath;
                command.Grayscale       = Convert.ToBoolean(o.Grayscale);
                openCombinedGif         = Convert.ToBoolean(o.OpenCombinedGif);
            });

            if (args.Contains("--help") || args.Contains("--version"))
            {
                await Task.CompletedTask;
            }
            else
            {
                await ExecuteCommandAsync(command, ct, openCombinedGif);
            }
        }
        public void ProcessPathCommand_Validation_Failures()
        {
            // Arrange
            var mediator = GetService <IMediator>();
            var ct       = new CancellationToken();
            var command  = new ProcessPathCommand();

            // Act & Assert
            var ex = Assert.ThrowsAsync <ValidationException>(() => mediator.Send(command, ct));

            Assert.AreEqual("One or more validation failures have occurred.", ex.Message);
            Assert.IsNotNull(ex.Failures);
            Assert.AreEqual(3, ex.Failures.Count);
            var firstEntry = ex.Failures[nameof(command.AmountPerAxis)];

            Assert.AreEqual(1, firstEntry.Length);
            Assert.AreEqual("'Amount Per Axis' must be greater than '0'.", firstEntry[0]);
            var secondEntry = ex.Failures[nameof(command.SourcePath)];

            Assert.AreEqual(1, secondEntry.Length);
            Assert.AreEqual("'Source Path' must not be empty.", secondEntry[0]);
            var thirdEntry = ex.Failures[nameof(command.DestinationPath)];

            Assert.AreEqual(1, thirdEntry.Length);
            Assert.AreEqual("'Destination Path' must not be empty.", thirdEntry[0]);
        }
示例#6
0
        public void ImageExtractor_ProcessAsync()
        {
            // Arrange
            var extractor = GetService <IImageExtractor>();
            var ct        = new CancellationToken();
            var command   = new ProcessPathCommand()
            {
                SourcePath      = GetDataPath("SMIR.Brain_3more.XX.XX.OT.6560.mha"),
                DestinationPath = GetTempPath(),
                AmountPerAxis   = 6
            };

            try
            {
                // Act
                var result = extractor.ProcessAsync(command, ct).Result;

                // Assert
                // 6 (per axis) * 3 (x, y, z) = 18
                Assert.AreEqual(18, result.Images.Count);
                Assert.AreEqual(5, (int)result.LabelCount);
            }
            finally
            {
                DeleteDirectory(command.DestinationPath);
            }
        }
示例#7
0
        private async Task ExecuteTestAsync(string[] args, CancellationToken ct)
        {
            var command = new ProcessPathCommand()
            {
                AmountPerAxis   = 10,
                DesiredSize     = 250,
                SourcePath      = Path.Combine(FileSystemHelper.BuildCurrentPath(), "data", "SMIR.Brain.XX.O.MR_Flair.36620.mha"),
                DestinationPath = Path.Combine(FileSystemHelper.BuildCurrentPath(), "temp", Guid.NewGuid().ToString("N"))
            };

            command.AxisTypes.Add(AxisType.Z);

            await ExecuteCommandAsync(command, ct, true);
        }
示例#8
0
        /// <inheritdoc/>
        public async Task <ProcessResultModel> ProcessAsync(ProcessPathCommand command, CancellationToken ct)
        {
            if (string.IsNullOrWhiteSpace(command.SourcePath))
            {
                throw new UnexpectedNullException("Empty source path.");
            }

            if (string.IsNullOrWhiteSpace(command.DestinationPath))
            {
                throw new UnexpectedNullException("Empty destination path.");
            }

            var sourceFs    = fileSystemStrategy.Create(command.SourcePath);
            var destFs      = fileSystemStrategy.Create(command.DestinationPath);
            var watermarkFs = fileSystemStrategy.Create(command.WatermarkSourcePath);

            var commandClone = command.DeepClone();

            commandClone.SourcePath          = sourceFs.BuildAbsolutePath(command.SourcePath);
            commandClone.DestinationPath     = destFs.BuildAbsolutePath(command.DestinationPath);
            commandClone.WatermarkSourcePath = watermarkFs.BuildAbsolutePath(command.WatermarkSourcePath);

            // Creates all directories and subdirectories in the specified path unless they already exist.
            destFs.Directory.CreateDirectory(commandClone.DestinationPath);

            // TODO: support zip files
            var result = await imageExtractor.ProcessAsync(commandClone, ct);

            // Set GIFs
            result.Gifs = await gifImageWriter.WriteAsync(
                command.DestinationPath, result.Images, command.BezierEasingTypePerAxis, ct);

            result.CombinedGif = await gifImageWriter.WriteAsync(
                command.DestinationPath, result.Images, "combined", command.BezierEasingTypeCombined, ct);

            // Set application version
            var appInfo = appInfoFactory.Create();

            result.Version = appInfo.AppVersion;

            // Write JSON and set filename
            await jsonWriter.WriteAsync(commandClone.DestinationPath, "output", result, (filename) => { result.JsonFilename = filename; });

            return(result);
        }
示例#9
0
        /// <summary>
        /// Executes the specified arguments asynchronous.
        /// </summary>
        /// <param name="args">The arguments.</param>
        /// <param name="ct">The cancellation token.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        /// <exception cref="ArgumentNullException">
        /// SourcePath
        /// or
        /// DestinationPath
        /// </exception>
        public async Task ExecuteAsync(string[] args, CancellationToken ct)
        {
            var  command         = new ProcessPathCommand();
            bool openCombinedGif = false;

            Parser.Default.ParseArguments <Options>(args)
            .WithParsed(o =>
            {
                command.DesiredSize     = o.DesiredSize;
                command.AmountPerAxis   = o.AmountPerAxis;
                command.SourcePath      = o.SourcePath;
                command.DestinationPath = o.DestinationPath;
                command.Grayscale       = Convert.ToBoolean(o.Grayscale);
                openCombinedGif         = Convert.ToBoolean(o.OpenCombinedGif);
            });

            await ExecuteCommandAsync(command, ct, openCombinedGif);
        }
示例#10
0
        private PositionAxisContainerModel <string> WriteImage(
            int position,
            IFileSystem fs,
            ProcessPathCommand command,
            T1 reader,
            AxisType axisType,
            ImageFormat imageFormat,
            string filename,
            BitmapWrapper watermark = null)
        {
            var bitmap = reader.ExtractPosition(axisType, position, command.OutputSize);

            if (bitmap != null)
            {
                if (command.Grayscale)
                {
                    bitmap = bitmap.To8bppIndexedGrayscale();
                }

                bitmap = bitmap.ToCenter(command.OutputSize, Color.Black);
                if (bitmap == null)
                {
                    throw new UnexpectedNullException("Bitmap could not be centered.");
                }

                if (watermark != null)
                {
                    bitmap = bitmap.AppendWatermark(watermark);
                }

                fs.File.WriteAllBytes(fs.Path.Combine(command.DestinationPath, filename), bitmap.ToByteArray(imageFormat));

                bitmap.Dispose();

                return(new PositionAxisContainerModel <string>(position, axisType, filename));
            }

            return(null);
        }
示例#11
0
        /// <summary>
        /// Returns "Crop to custom selection" composite command.
        /// </summary>
        /// <param name="path">Custom selection path.</param>
        /// <param name="pathBounds">Selection path bounds.</param>
        /// <param name="crop">Crop command.</param>
        /// <returns>Crop command for custom selection.</returns>
        ProcessingCommandBase GetCropToPathCommand(
            GraphicsPath path,
            RectangleF pathBounds,
            CropCommand crop)
        {
            Rectangle viewerImageRect = new Rectangle(0, 0, _viewer.Image.Width, _viewer.Image.Height);

            crop.RegionOfInterest = new RegionOfInterest(GetBoundingRect(RectangleF.Intersect(pathBounds, viewerImageRect)));

            // overlay command
            _overlayImage = crop.Execute(_viewer.Image);
            OverlayCommand overlay = new OverlayCommand(_overlayImage);

            // overlay with path command
            ProcessPathCommand overlayWithPath = new ProcessPathCommand(overlay, path);

            // clear image command
            ClearImageCommand clearImage = new ClearImageCommand(Color.Transparent);

            // create composite command: clear, overlay with path, crop
            return(new CompositeCommand(clearImage, overlayWithPath, crop));
        }
示例#12
0
        public void ProcessPathCommand()
        {
            // Arrange
            var mediator = GetService <IMediator>();
            var ct       = new CancellationToken();
            var command  = new ProcessPathCommand()
            {
                SourcePath      = GetDataPath("SMIR.Brain_3more.XX.XX.OT.6560.mha"),
                DestinationPath = GetTempPath(),
                AmountPerAxis   = 6,
                AxisTypes       = new HashSet <AxisType>
                {
                    AxisType.X,
                    AxisType.Y,
                    AxisType.Z
                }
            };

            try
            {
                // Act
                var result = mediator.Send(command, ct).Result;

                // Assert
                // 6 (per axis) * 3 (x, y, z) = 18
                Assert.AreEqual(18, result.Images.Count);
                Assert.AreEqual(5, result.LabelCount);
                Assert.AreEqual(160, result.Size[0]);
                Assert.AreEqual(216, result.Size[1]);
                Assert.AreEqual(176, result.Size[2]);
            }
            finally
            {
                DeleteDirectory(command.DestinationPath);
            }
        }
        /// <inheritdoc/>
        protected override async Task <ProcessResultModel> ProtectedHandleAsync(ProcessObjectCommand request, CancellationToken cancellationToken)
        {
            context.BeginTransaction();

            var objectEntity = await context.ObjectRepository.GetFirstOrDefaultAsync(e => e.Id == Guid.Parse(request.Id), cancellationToken);

            if (objectEntity == null)
            {
                throw new UnexpectedNullException($"{nameof(ObjectEntity)} not found.");
            }

            // Create temporary directory and use it as destination path
            var tempDestPath = fileSystem.Path.Combine(configuration.WorkingDirectory, "Temp", Guid.NewGuid().ToString());

            fileSystem.Directory.CreateDirectory(tempDestPath);

            // TODO: extract if needed, update the ObjectEntity.UncompressedPath
            // and use the extracted directory as source path
            var pathRequest = new ProcessPathCommand()
            {
                SourcePath               = fileSystem.Path.Combine(configuration.WorkingDirectory, objectEntity.SourcePath),
                DestinationPath          = tempDestPath,
                DesiredSize              = request.DesiredSize,
                AmountPerAxis            = request.AmountPerAxis,
                AxisTypes                = request.AxisTypes,
                ImageFormat              = request.ImageFormat,
                BezierEasingTypePerAxis  = request.BezierEasingTypePerAxis,
                BezierEasingTypeCombined = request.BezierEasingTypeCombined,
                Grayscale                = request.Grayscale
            };

            // Start the processing
            var result = await mediator.Send(pathRequest, cancellationToken);

            if (result == null)
            {
                throw new UnexpectedNullException($"The processing result of object {request.Id} was null.");
            }

            // Move content of temporary directory and delete it
            var resultsDirectoryName = "Results";
            var resultsPath          = fileSystem.Path.Combine(configuration.WorkingDirectory, resultsDirectoryName);
            var baseDestPath         = fileSystem.Path.Combine(resultsDirectoryName, result.Id);
            var destPath             = fileSystem.Path.Combine(configuration.WorkingDirectory, baseDestPath);

            fileSystem.Directory.CreateDirectory(resultsPath);
            fileSystem.Directory.Move(tempDestPath, destPath);

            var resultEntity = await context.ResultRepository.GetFirstOrDefaultAsync(e => e.Id == Guid.Parse(result.Id), cancellationToken);

            if (resultEntity == null)
            {
                throw new UnexpectedNullException($"{nameof(ResultEntity)} not found.");
            }

            // Update BaseFsPath of ResultEntity
            resultEntity.BasePath     = baseDestPath;
            resultEntity.ModifiedDate = DateTime.UtcNow;
            context.ResultRepository.Update(resultEntity);

            await context.SaveChangesAsync(cancellationToken);

            context.CommitTransaction();

            return(result);
        }
示例#14
0
        /// <summary>
        /// Executes image processing command synchronously or asynchronously.
        /// </summary>
        /// <param name="command">Command to execute.</param>
        /// <param name="async">A value indicating whether to execute command asynchronously.</param>
        public bool ExecuteProcessingCommand(ProcessingCommandBase command, bool async)
        {
            RectangularSelectionToolWithCopyPaste rectSelectionTool = CompositeVisualTool.FindVisualTool <RectangularSelectionToolWithCopyPaste>(_viewer.VisualTool);
            CustomSelectionTool customSelectionTool = CompositeVisualTool.FindVisualTool <CustomSelectionTool>(_viewer.VisualTool);

            if (rectSelectionTool != null)
            {
                // set the region of interest
                Rectangle selectionRectangle = ViewerSelectionRectangle;
                ProcessingCommandWithRegion commandWorkWithRegion = command as ProcessingCommandWithRegion;
                if (commandWorkWithRegion != null)
                {
                    commandWorkWithRegion.RegionOfInterest = new RegionOfInterest(selectionRectangle.Left, selectionRectangle.Top, selectionRectangle.Width, selectionRectangle.Height);
                }
                else if (command is DrawImageCommand)
                {
                    ((DrawImageCommand)command).DestRect = selectionRectangle;
                }
                else if (!selectionRectangle.IsEmpty)
                {
                    MessageBox.Show("Selected image processing command cannot work with regions. Entire image will be processed.",
                                    "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
            else if (customSelectionTool != null)
            {
                RectangleF selectionBBox = RectangleF.Empty;
                if (customSelectionTool.Selection != null)
                {
                    selectionBBox = customSelectionTool.Selection.GetBoundingBox();
                }
                if (selectionBBox.Width >= 1 && selectionBBox.Height >= 1)
                {
                    if (command is ChangePixelFormatCommand ||
                        command is ChangePixelFormatToBgrCommand ||
                        command is ChangePixelFormatToBlackWhiteCommand ||
                        command is ChangePixelFormatToGrayscaleCommand ||
                        command is ChangePixelFormatToPaletteCommand ||
                        command is RotateCommand ||
                        command is ResampleCommand ||
                        command is ResizeCommand ||
                        !command.CanModifyImage)
                    {
                        MessageBox.Show("Selected image processing command cannot work with custom selection. Entire image will be processed.",
                                        "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        GraphicsPath path       = customSelectionTool.Selection.GetAsGraphicsPath();
                        RectangleF   pathBounds = path.GetBounds();
                        if (pathBounds.Width > 0 && pathBounds.Height > 0)
                        {
                            if (command is CropCommand)
                            {
                                // crop to custom selection
                                command = GetCropToPathCommand(path, pathBounds, (CropCommand)command);
                                // clear selection
                                customSelectionTool.Selection = null;
                            }
                            else
                            {
                                // process path
                                command = new ProcessPathCommand(command, path);
                            }
                        }
                        else
                        {
                            MessageBox.Show("Selected path is empty.",
                                            "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return(false);
                        }
                    }
                }
            }

            // get a reference to the image for processing
            VintasoftImage imageToProcess = _viewer.Image;

            ProcessingCommandBase executeCommand = command;

            if (_executeMultithread)
            {
                ParallelizingProcessingCommand parallelizingCommand = new ParallelizingProcessingCommand(command);
                if (command is ProcessingCommandWithRegion)
                {
                    parallelizingCommand.RegionOfInterest = ((ProcessingCommandWithRegion)command).RegionOfInterest;
                }
                executeCommand = parallelizingCommand;
            }

            if (UndoManager != null)
            {
                _imageProcessingUndoMonitor = new ImageProcessingUndoMonitor(UndoManager, executeCommand);
            }

            // subscribe to the events of the image processing command
            executeCommand.Started  += new EventHandler <ImageProcessingEventArgs>(command_Started);
            executeCommand.Progress += new EventHandler <ImageProcessingProgressEventArgs>(command_Progress);
            executeCommand.Finished += new EventHandler <ImageProcessedEventArgs>(command_Finished);

            executeCommand.ExpandSupportedPixelFormats = ExpandSupportedPixelFormats;
            executeCommand.RestoreSourcePixelFormat    = false;

            // specify that image processing command is working (several commands cannot work together)
            _isImageProcessingWorking = true;
            // get the start time of the image processing command
            _processingCommandStartTime = DateTime.Now;

            // if image processing command should be executed asynchronously
            if (async)
            {
                // start the image processing command asynchronously
                ProcessingCommandTask executor = new ProcessingCommandTask(executeCommand, imageToProcess);
                executor.ImageProcessingExceptionOccurs += new EventHandler(executor_ImageProcessingExceptionOccurs);
                Thread thread = new Thread(executor.Execute);
                thread.IsBackground = true;
                thread.Start();
            }
            // if image processing command should be executed synchronously
            else
            {
                try
                {
                    // execute the image processing command synchronously
                    executeCommand.ExecuteInPlace(imageToProcess);
                }
                catch (Exception ex)
                {
                    executor_ImageProcessingExceptionOccurs(this, EventArgs.Empty);
                    DemosTools.ShowErrorMessage(ex);
                    return(false);
                }
            }

            return(true);
        }
示例#15
0
        public void ImageService_ProcessAsync()
        {
            // Arrange
            var service = GetService <IImageService>();
            var ct      = new CancellationToken();
            var command = new ProcessPathCommand()
            {
                AmountPerAxis   = 10,
                DesiredSize     = 250,
                SourcePath      = GetDataPath("SMIR.Brain_3more.XX.XX.OT.6560.mha"),
                DestinationPath = GetTempPath()
            };

            command.AxisTypes.Add(AxisType.Z);
            var expected = @"{
  ""resultType"": 1,
  ""labelCount"": 5,
  ""images"": [
    {
      ""position"": 0,
      ""axisType"": 2,
      ""entity"": ""Z_0.png""
    },
    {
      ""position"": 1,
      ""axisType"": 2,
      ""entity"": ""Z_1.png""
    },
    {
      ""position"": 2,
      ""axisType"": 2,
      ""entity"": ""Z_2.png""
    },
    {
      ""position"": 3,
      ""axisType"": 2,
      ""entity"": ""Z_3.png""
    },
    {
      ""position"": 4,
      ""axisType"": 2,
      ""entity"": ""Z_4.png""
    },
    {
      ""position"": 5,
      ""axisType"": 2,
      ""entity"": ""Z_5.png""
    },
    {
      ""position"": 6,
      ""axisType"": 2,
      ""entity"": ""Z_6.png""
    },
    {
      ""position"": 7,
      ""axisType"": 2,
      ""entity"": ""Z_7.png""
    },
    {
      ""position"": 8,
      ""axisType"": 2,
      ""entity"": ""Z_8.png""
    },
    {
      ""position"": 9,
      ""axisType"": 2,
      ""entity"": ""Z_9.png""
    }
  ],
  ""gifs"": [
    {
      ""axisType"": 2,
      ""entity"": ""Z.gif""
    }
  ],
  ""combinedGif"": ""combined.gif"",
  ""id"": null,
  ""createdDate"": ""0001-01-01T00:00:00"",
  ""modifiedDate"": ""0001-01-01T00:00:00"",
  ""version"": ""0.0.3"",
  ""jsonFilename"": ""output.json"",
  ""discriminator"": ""ProcessResultModel""
}";

            try
            {
                // Act
                var result = service.ProcessAsync(command, ct).Result;
                var json   = File.ReadAllText(Path.Combine(command.DestinationPath, result.JsonFilename));

                // Assert
                Assert.AreEqual(command.AmountPerAxis, result.Images.Count);
                Assert.AreEqual(5, result.LabelCount);
                Assert.AreEqual(expected, json);
            }
            finally
            {
                DeleteDirectory(command.DestinationPath);
            }
        }
        /// <inheritdoc/>
        protected override async Task <ProcessResultModel> ProtectedHandleAsync(ProcessObjectCommand request, CancellationToken cancellationToken)
        {
            var objectEntity = await Context.ObjectRepository.GetFirstOrDefaultAsync(e => e.Id == Guid.Parse(request.Id), cancellationToken);

            if (objectEntity == null)
            {
                throw new UnexpectedNullException($"{nameof(ObjectEntity)} not found.");
            }

            var directoryName = fileSystem.Path.GetDirectoryName(objectEntity.SourcePath);

            if (!directoryName.EndsWith(objectEntity.Id.ToString()))
            {
                throw new AmiException(string.Format(
                                           "The directory name of object {0} ends with an unexpected name: {1}",
                                           objectEntity.Id,
                                           directoryName));
            }

            // Create temporary directory and use it as destination path
            var tempDestPath = fileSystem.Path.Combine(configuration.Options.WorkingDirectory, "Temp", Guid.NewGuid().ToString());

            fileSystem.Directory.CreateDirectory(tempDestPath);

            var fullSourcePath = fileSystem.Path.Combine(configuration.Options.WorkingDirectory, objectEntity.SourcePath);

            var pathRequest = new ProcessPathCommand()
            {
                SourcePath               = fullSourcePath,
                DestinationPath          = tempDestPath,
                OutputSize               = request.OutputSize,
                AmountPerAxis            = request.AmountPerAxis,
                Delay                    = request.Delay,
                AxisTypes                = request.AxisTypes,
                ImageFormat              = request.ImageFormat,
                BezierEasingTypePerAxis  = request.BezierEasingTypePerAxis,
                BezierEasingTypeCombined = request.BezierEasingTypeCombined,
                Grayscale                = request.Grayscale
            };

            // Extract archive if needed
            if (archiveReader.IsArchive(fullSourcePath))
            {
                var extractedPath     = fileSystem.Path.Combine(directoryName, "Extracted");
                var fullExtractedPath = fileSystem.Path.Combine(configuration.Options.WorkingDirectory, extractedPath);

                // Use the extracted directory as source path
                pathRequest.SourcePath = fullExtractedPath;

                if (string.IsNullOrWhiteSpace(objectEntity.ExtractedPath))
                {
                    fileSystem.Directory.CreateDirectory(fullExtractedPath);

                    await archiveExtractor.ExtractAsync(fullSourcePath, fullExtractedPath, cancellationToken);

                    objectEntity.ModifiedDate  = DateTime.UtcNow;
                    objectEntity.ExtractedPath = extractedPath;

                    Context.ObjectRepository.Update(objectEntity);
                }
            }

            // Start the processing
            var result = await mediator.Send(pathRequest, cancellationToken);

            if (result == null)
            {
                throw new UnexpectedNullException($"The processing result of object {request.Id} was null.");
            }

            // Ensure "Results" directory exists
            var resultsDirectoryName = "Results";
            var resultsPath          = fileSystem.Path.Combine(configuration.Options.WorkingDirectory, resultsDirectoryName);

            fileSystem.Directory.CreateDirectory(resultsPath);

            // Move content of temporary directory and delete it
            var baseDestPath = fileSystem.Path.Combine(resultsDirectoryName, result.Id);
            var destPath     = fileSystem.Path.Combine(configuration.Options.WorkingDirectory, baseDestPath);

            fileSystem.Directory.Move(tempDestPath, destPath);

            var resultEntity = await Context.ResultRepository.GetFirstOrDefaultAsync(e => e.Id == Guid.Parse(result.Id), cancellationToken);

            if (resultEntity == null)
            {
                throw new UnexpectedNullException($"{nameof(ResultEntity)} not found.");
            }

            // Update BaseFsPath of ResultEntity
            resultEntity.BasePath     = baseDestPath;
            resultEntity.ModifiedDate = DateTime.UtcNow;
            Context.ResultRepository.Update(resultEntity);

            await Context.SaveChangesAsync(cancellationToken);

            return(result);
        }
示例#17
0
        /// <inheritdoc/>
        public async Task <ProcessResultModel> ProcessAsync(ProcessPathCommand command, CancellationToken ct)
        {
            Ensure.ArgumentNotNull(command, nameof(command));
            Ensure.ArgumentNotNull(ct, nameof(ct));

            ImageFormat imageFormat    = GetImageFormat(command.ImageFormat);
            string      imageExtension = imageFormat.FileExtensionFromEncoder();

            if (string.IsNullOrWhiteSpace(imageExtension))
            {
                throw new UnexpectedNullException("Image file extension could not be determined.");
            }

            var fs = fileSystemStrategy.Create(command.DestinationPath);

            if (fs == null)
            {
                throw new UnexpectedNullException("Filesystem could not be created based on the destination path.");
            }

            var reader = readerFactory.Create();

            if (reader == null)
            {
                throw new UnexpectedNullException("Image reader could not be created.");
            }

            await reader.InitAsync(command.SourcePath, ct);

            reader.Mapper = new AxisPositionMapper(command.AmountPerAxis, reader.Width, reader.Height, reader.Depth);

            PreProcess(reader, imageFormat, command.AmountPerAxis, command.OutputSize);

            var result = new ProcessResultModel
            {
                LabelCount = Convert.ToInt32(reader.GetLabelCount()),
                Size       = new int[] { reader.Width, reader.Height, reader.Depth }
            };

            ISet <AxisType> axisTypes = new HashSet <AxisType>(command.AxisTypes);

            if (axisTypes.Count == 0)
            {
                axisTypes = new HashSet <AxisType> {
                    AxisType.Z
                };
            }

            BitmapWrapper watermark = null;

            if (!string.IsNullOrWhiteSpace(command.WatermarkSourcePath))
            {
                BitmapReader bitmapReader    = new BitmapReader();
                var          watermarkBitmap = await bitmapReader.ReadAsync(command.WatermarkSourcePath, command.OutputSize, ct);

                if (watermarkBitmap == null)
                {
                    throw new UnexpectedNullException("Watermark could not be read.");
                }

                watermark = new BitmapWrapper(watermarkBitmap);
            }

            var images = new List <PositionAxisContainerModel <string> >();

            foreach (AxisType axisType in axisTypes)
            {
                for (int i = 0; i < reader.Mapper.GetLength(axisType); i++)
                {
                    ct.ThrowIfCancellationRequested();

                    string filename = $"{axisType}_{i}{imageExtension}";

                    var image = WriteImage(i, fs, command, reader, axisType, imageFormat, filename, watermark);
                    if (image != null)
                    {
                        images.Add(image);
                    }
                }
            }

            reader.Dispose();

            result.Images = images.OrderBy(e => e.Position).ToList();

            return(result);
        }
        /// <inheritdoc/>
        public async Task <ProcessResultModel> ProcessAsync(ProcessPathCommand command, CancellationToken ct)
        {
            Ensure.ArgumentNotNull(command, nameof(command));
            Ensure.ArgumentNotNull(ct, nameof(ct));

            if (string.IsNullOrWhiteSpace(command.SourcePath))
            {
                throw new UnexpectedNullException("Empty source path.");
            }

            if (string.IsNullOrWhiteSpace(command.DestinationPath))
            {
                throw new UnexpectedNullException("Empty destination path.");
            }

            var sourceFs    = fileSystemStrategy.Create(command.SourcePath);
            var destFs      = fileSystemStrategy.Create(command.DestinationPath);
            var watermarkFs = fileSystemStrategy.Create(command.WatermarkSourcePath);

            var commandClone = command.DeepClone();

            commandClone.SourcePath          = sourceFs.BuildAbsolutePath(command.SourcePath);
            commandClone.DestinationPath     = destFs.BuildAbsolutePath(command.DestinationPath);
            commandClone.WatermarkSourcePath = watermarkFs.BuildAbsolutePath(command.WatermarkSourcePath);

            // Creates all directories and subdirectories in the specified path unless they already exist.
            destFs.Directory.CreateDirectory(commandClone.DestinationPath);

            // SourcePath can be a directory, archive or file
            if (archiveReader.IsArchive(commandClone.SourcePath))
            {
                var extractedPath = destFs.Path.Combine(commandClone.DestinationPath, "Extracted");
                destFs.Directory.CreateDirectory(extractedPath);
                await archiveExtractor.ExtractAsync(commandClone.SourcePath, extractedPath, ct);

                // Use the extracted directory as source path
                commandClone.SourcePath = extractedPath;
            }

            var result = await imageExtractor.ProcessAsync(commandClone, ct);

            if (result == null)
            {
                throw new UnexpectedNullException("The images could not be processed.");
            }

            // Set GIFs
            result.Gifs = await gifImageWriter.WriteAsync(
                commandClone.DestinationPath, result.Images, commandClone.Delay, commandClone.BezierEasingTypePerAxis, ct);

            result.CombinedGif = await gifImageWriter.WriteAsync(
                commandClone.DestinationPath, result.Images, "combined", commandClone.Delay, commandClone.BezierEasingTypeCombined, ct);

            // Set application version
            var appInfo = appInfoFactory.Create();

            result.Version = appInfo.AppVersion;

            // Write JSON and set filename
            await jsonWriter.WriteAsync(commandClone.DestinationPath, "output", result, (filename) => { result.JsonFilename = filename; });

            return(result);
        }
        /// <summary>
        /// Processes the images asynchronous.
        /// </summary>
        /// <param name="command">The command information.</param>
        /// <param name="ct">The cancellation token.</param>
        /// <returns>
        /// The result of the image processing.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// command
        /// or
        /// ct
        /// </exception>
        /// <exception cref="UnexpectedNullException">
        /// Image file extension could not be determined.
        /// or
        /// Filesystem could not be created based on the destination path.
        /// or
        /// Image reader could not be created.
        /// or
        /// Watermark could not be read.
        /// or
        /// Bitmap could not be centered.
        /// </exception>
        public async Task <ProcessResultModel> ProcessAsync(ProcessPathCommand command, CancellationToken ct)
        {
            if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            if (ct == null)
            {
                throw new ArgumentNullException(nameof(ct));
            }

            var result         = new ProcessResultModel();
            var imageFormat    = GetImageFormat(command.ImageFormat);
            var imageExtension = imageFormat.FileExtensionFromEncoder();

            if (string.IsNullOrWhiteSpace(imageExtension))
            {
                throw new UnexpectedNullException("Image file extension could not be determined.");
            }

            var fs = fileSystemStrategy.Create(command.DestinationPath);

            if (fs == null)
            {
                throw new UnexpectedNullException("Filesystem could not be created based on the destination path.");
            }

            var reader = readerFactory.Create();

            if (reader == null)
            {
                throw new UnexpectedNullException("Image reader could not be created.");
            }

            await reader.InitAsync(command.SourcePath, ct);

            reader.Mapper = new AxisPositionMapper(Convert.ToUInt32(command.AmountPerAxis), reader.Width, reader.Height, reader.Depth);

            PreProcess(reader, imageFormat, Convert.ToUInt32(command.AmountPerAxis), Convert.ToUInt32(command.DesiredSize));

            result.LabelCount = Convert.ToInt32(reader.GetLabelCount());

            ISet <AxisType> axisTypes = new HashSet <AxisType>(command.AxisTypes);

            if (axisTypes.Count == 0)
            {
                axisTypes = reader.GetRecommendedAxisTypes();
            }

            BitmapWrapper watermark = null;

            if (!string.IsNullOrWhiteSpace(command.WatermarkSourcePath))
            {
                BitmapReader bitmapReader    = new BitmapReader();
                var          watermarkBitmap = await bitmapReader.ReadAsync(command.WatermarkSourcePath, Convert.ToUInt32(command.DesiredSize), ct);

                if (watermarkBitmap == null)
                {
                    throw new UnexpectedNullException("Watermark could not be read.");
                }

                watermark = new BitmapWrapper(watermarkBitmap);
            }

            var images = new List <PositionAxisContainerModel <string> >();

            foreach (AxisType axisType in axisTypes)
            {
                for (int i = 0; i < command.AmountPerAxis; i++)
                {
                    ct.ThrowIfCancellationRequested();
                    string filename = $"{axisType}_{i}{imageExtension}";
                    var    bitmap   = reader.ExtractPosition(axisType, Convert.ToUInt32(i), Convert.ToUInt32(command.DesiredSize));
                    if (bitmap != null)
                    {
                        if (command.Grayscale)
                        {
                            bitmap = bitmap.To8bppIndexedGrayscale();
                        }

                        bitmap = bitmap.ToCenter(Convert.ToUInt32(command.DesiredSize), Color.Black);
                        if (bitmap == null)
                        {
                            throw new UnexpectedNullException("Bitmap could not be centered.");
                        }

                        if (watermark != null)
                        {
                            bitmap = bitmap.AppendWatermark(watermark);
                        }

                        fs.File.WriteAllBytes(fs.Path.Combine(command.DestinationPath, filename), bitmap.ToByteArray(imageFormat));
                        images.Add(new PositionAxisContainerModel <string>(Convert.ToUInt32(i), axisType, filename));
                    }
                }
            }

            result.Images = images.OrderBy(e => e.Position).ToList();

            return(result);
        }