public async Task <ImageInfo> UploadImage(Stream imageStream, string partitionKey) { _logger.LogDebug(CheckingImage); var imageFormat = _metadataReader.DetectFormat(imageStream); if (imageFormat != null) { _logger.LogDebug(imageFormat.ToString()); } var limits = _limitationSettings.Value; if (imageFormat == null || !limits.Types.Contains(imageFormat.ImageType.ToString())) { throw new ValidationException(string.Format(UnsupportedFormat, string.Join(",", limits.Types))); } var imageSize = _metadataReader.ReadSize(imageStream); _logger.LogDebug(imageSize.ToString()); string sizeValidationError = ValidateSize(imageSize, limits); if (sizeValidationError != null) { throw new ValidationException(sizeValidationError); } //Firstly, saving the image stream to the blob storage string imageId = _imageIdentifierProvider.GenerateUniqueId(); string imageName = _imageIdentifierProvider.GetImageName(imageId, imageFormat.FileExtension); var uploadImageResult = await _blobStorage.UploadImage(imageName, imageStream, ImageSizeType.Original, imageFormat.MimeType, CancellationToken.None); _logger.LogDebug(UploadedToBlobStorage, imageId); //Image stream is no longer needed at this stage imageStream.Dispose(); //Next, saving the metadata object of this image //When the program unexpectedly fails at this stage, there will be just a blob file not connected to any metadata object //and therefore the image will be unavailable to the clients. In most cases it is just fine. await _metadataStorage.SetMetadata(new ImageMetadata { Id = imageId, Name = imageName, DateAddedUtc = uploadImageResult.DateAdded.DateTime, Height = imageSize.Height, Width = imageSize.Width, MD5Hash = uploadImageResult.MD5Hash, SizeBytes = imageSize.Bytes, MimeType = imageFormat.MimeType, ImageType = (Storage.Abstractions.Models.ImageType)imageFormat.ImageType, FileExtension = imageFormat.FileExtension, PartitionKey = partitionKey }, CancellationToken.None); _logger.LogDebug(UploadedToMetadataStorage); return(new ImageInfo { Id = imageId, Hash = uploadImageResult.MD5Hash, DateAdded = uploadImageResult.DateAdded, Url = uploadImageResult.Url.ToString(), Bytes = imageSize.Bytes, Height = imageSize.Height, Width = imageSize.Width, MimeType = imageFormat.MimeType }); }
public async Task <List <ImageThumbnailGeneratingResult> > GenerateThumbnails(string imageId, string partitionKey) { var imageMetadataList = await _metadataStorage.GetMetadata(new List <string> { imageId }, partitionKey, CancellationToken.None); if (imageMetadataList == null || !imageMetadataList.Any()) { _logger.LogInformation(ImageNotFound, imageId); return(null); } var imageMetadata = imageMetadataList[0]; imageMetadata.Thumbnails = new List <ImageThumbnail>(); _logger.LogDebug(MetadataReceived, imageMetadata.Id, imageMetadata.Width, imageMetadata.Height); if (imageMetadata.Width <= _thumbnailTargetWidth.Last()) { _logger.LogInformation(ImageSmallerThanTargetWidth, imageMetadata.Id, imageMetadata.Width); return(new List <ImageThumbnailGeneratingResult>(0)); } using var originalImageStream = await _blobStorage.DownloadImage(imageMetadata.Name, ImageSizeType.Original, CancellationToken.None); _logger.LogDebug(ImageDownloaded, imageMetadata.Id); StorageImageType imageType = imageMetadata.ImageType; string mimeType = imageMetadata.MimeType; string fileExtension = imageMetadata.FileExtension; if (imageType == StorageImageType.BMP) { imageType = StorageImageType.PNG; mimeType = PngMimeType; fileExtension = PngFileExtension; } var imageStream = originalImageStream; foreach (var targetWidth in _thumbnailTargetWidth) { if (targetWidth >= imageMetadata.Width) { continue; } var resizingResult = _imageResizing.Resize(imageStream, (ImageType)imageType, targetWidth); _logger.LogDebug(ImageResized, imageMetadata.Id, resizingResult.Size); var thumbnailImageId = _imageIdentifierProvider.GenerateUniqueId(); var thumbnailImageName = _imageIdentifierProvider.GetImageName(thumbnailImageId, fileExtension); var uploadedBlob = await _blobStorage.UploadImage(thumbnailImageName, resizingResult.Image, ImageSizeType.Thumbnail, mimeType, CancellationToken.None); imageMetadata.Thumbnails.Add(new ImageThumbnail { Id = thumbnailImageId, Name = thumbnailImageName, MD5Hash = uploadedBlob.MD5Hash, DateAddedUtc = uploadedBlob.DateAdded.DateTime, MimeType = mimeType, Height = resizingResult.Size.Height, Width = resizingResult.Size.Width, SizeBytes = resizingResult.Size.Bytes }); imageStream = resizingResult.Image; } imageStream.Dispose(); imageMetadata.Thumbnails.Reverse(); await _metadataStorage.SetMetadata(imageMetadata, CancellationToken.None); _logger.LogInformation(ThumbnailsGenerated, imageMetadata.Thumbnails.Count, imageId); return(imageMetadata.Thumbnails.Select(x => new ImageThumbnailGeneratingResult { Id = x.Id, Width = x.Width, Height = x.Height, MimeType = x.MimeType }).ToList()); }