/// <summary>
        /// Encodes an image for storage.
        /// </summary>
        /// <param name="imageStream">The image to encode.</param>
        /// <returns>The encoded image, or null if decoding fails.</returns>
        /// <remarks>
        /// The image returned is guaranteed to have no side longer than
        /// <see cref="F:HospitalAllocation.Providers.Image.Database.DbImageProvider.MaxSideLength"/> pixels.
        /// </remarks>
        private static SKData EncodeImage(IImageStream imageStream)
        {
            // Get the image
            var imageArray = new byte[imageStream.Length];
            var stream     = new MemoryStream(imageArray);

            imageStream.CopyTo(stream);

            var data  = SKData.CreateCopy(imageArray);
            var image = SKImage.FromEncodedData(data);

            // Decode failed
            if (image == null)
            {
                return(null);
            }

            // Resize the image if required
            if (Math.Max(image.Height, image.Width) > MaxSideLength)
            {
                int   resizedHeight;
                int   resizedWidth;
                float scale;
                if (image.Height > image.Width)
                {
                    resizedHeight = MaxSideLength;
                    scale         = ((float)resizedHeight / image.Height);
                    resizedWidth  = (int)Math.Round(image.Width * scale);
                }
                else
                {
                    resizedWidth  = MaxSideLength;
                    scale         = ((float)resizedWidth / image.Width);
                    resizedHeight = (int)Math.Round(image.Height * scale);
                }

                var surface = SKSurface.Create(new SKImageInfo(resizedWidth, resizedHeight));
                var paint   = new SKPaint
                {
                    FilterQuality = SKFilterQuality.High
                };
                surface.Canvas.Scale(scale);
                surface.Canvas.DrawImage(image, 0, 0, paint);
                surface.Canvas.Flush();

                image = surface.Snapshot();
            }

            // Encode the image
            return(image.Encode(SKEncodedImageFormat.Jpeg, JpegQualityLevel));
        }
Esempio n. 2
0
        /// <summary>
        /// Replace the image at the given index with the given one
        /// </summary>
        /// <param name="id">Identifier.</param>
        /// <param name="newImage">New image.</param>
        public void ReplaceImage(int id, IImageStream newImage)
        {
            FileInfo file = GetImageFileFromIndex(id);

            if (file == null || !file.Exists)
            {
                throw new ArgumentException(String.Format("Image with ID {0} does not exist.", id));
            }

            using (var stream = file.OpenWrite())
            {
                newImage.CopyTo(stream);
            }
        }
Esempio n. 3
0
        public IActionResult RetrieveImage(int id)
        {
            IImageStream image = _imageProvider.GetImage(id);

            if (image == null)
            {
                return(BadRequest(new ErrorResponse("No such image")));
            }

            // We need to copy the image to an internal memory stream in order
            // to transfer it out with a byte array. This is probably inefficient
            // since we copy once to the filesystem to memory and then from
            // memory to HTTP - worth refactoring later
            var dataStream = new MemoryStream();

            image.CopyTo(dataStream);
            return(File(dataStream.ToArray(), image.Format.ContentTypeString()));
        }
Esempio n. 4
0
        /// <summary>
        /// Takes an image from an image stream and saves it to the directory
        /// in the conventional format of this image provider
        /// </summary>
        /// <returns>The image.</returns>
        /// <param name="imageData">Image data.</param>
        public int CreateImage(IImageStream imageData)
        {
            // Always assign to a deleted index first if possible
            int index = -1;

            if (_deletedIndices.Any())
            {
                index = _deletedIndices.FirstOrDefault();
                _deletedIndices.Remove(index);
            }
            else
            {
                index = _nextImageIndex;
                _nextImageIndex++;
            }

            using (var stream = FileForNewImage(index, imageData.Format).OpenWrite())
            {
                imageData.CopyTo(stream);
            }

            return(index);
        }