private Stream GetImageThumbnailStream(string type, string imageGuid, string width = null, string height = null) { if (type != "T" && type != "R" && type != "M") { throw new Exception("Unsupported image type"); } idCatalogItem catalogItem = null; Stream imageStream = null; using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, readUncommittedTransactionOptions)) { catalogItem = db.idCatalogItem.Include("idFilePath").Single(x => x.GUID == imageGuid); if (catalogItem == null) { throw new Exception("CatalogItem not found"); } if (type == "R" && catalogItem.idHasRecipe == 0) { throw new Exception("Image has no recipe"); } //Check if CatalogItem has a recipe, if yes try to get the recipe image if (type == "M" && catalogItem.idHasRecipe > 0) { type = "R"; } Boolean keepAspectRatio = Boolean.Parse(ConfigurationManager.AppSettings["KeepAspectRatio"]); Boolean setGenericVideoThumbnailOnError = Boolean.Parse(ConfigurationManager.AppSettings["SetGenericVideoThumbnailOnError"]); idThumbs thumb = null; lock (dbThumbs) { //Searching with FirstOrDefault because PhotoSupreme sometimes stores the Thumbnail twice thumb = dbThumbs.idThumbs.FirstOrDefault(x => x.ImageGUID == imageGuid && x.idType == type); //If recipe image is not found, return the M image, //because the programm cannot yet generate the recipe image if (thumb == null && type == "R") { type = "M"; //Searching with FirstOrDefault because PhotoSupreme sometimes stores the Thumbnail twice thumb = dbThumbs.idThumbs.FirstOrDefault(x => x.ImageGUID == imageGuid && x.idType == type); } } if (thumb == null && Boolean.Parse(ConfigurationManager.AppSettings["CreateThumbnails"])) { SaveImageThumbnailResult result = StaticFunctions.SaveImageThumbnail(catalogItem, ref db, ref dbThumbs, new List <String>() { type }, keepAspectRatio, setGenericVideoThumbnailOnError); foreach (Exception ex in result.Exceptions) { log.Error(ex.ToString()); } if (result.ImageStreams.Count > 0) { imageStream = result.ImageStreams.First(); if (IsRequestRest()) { WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg"; } log.Info(String.Format("Client {0}:{1} called GetImageThumbnail with type: {2} imageGuid: {3} (returned resizedImageStream)", clientEndpoint.Address, clientEndpoint.Port, type, imageGuid)); } else { log.Info(String.Format("Client {0}:{1} called GetImageThumbnail with type: {2} imageGuid: {3} (returned null)", clientEndpoint.Address, clientEndpoint.Port, type, imageGuid)); } } else { imageStream = new MemoryStream(thumb.idThumb); if (IsRequestRest()) { WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg"; } log.Info(String.Format("Client {0}:{1} called GetImageThumbnail with type: {2} imageGuid: {3} (returned imageStream)", clientEndpoint.Address, clientEndpoint.Port, type, imageGuid)); } scope.Complete(); } if (width != null && height != null) { TransformGroup transformGroup = new TransformGroup(); BitmapSource bitmapSource = StaticFunctions.GetBitmapFrameFromImageStream(imageStream, "JPG"); StaticFunctions.Resize(ref bitmapSource, ref transformGroup, int.Parse(width), int.Parse(height)); if (transformGroup != null && transformGroup.Children.Count > 0) { TransformedBitmap tb = new TransformedBitmap(); tb.BeginInit(); tb.Source = bitmapSource; tb.Transform = transformGroup; tb.EndInit(); bitmapSource = tb; BitmapFrame transformedBitmapFrame = BitmapFrame.Create(bitmapSource); JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(transformedBitmapFrame); imageStream = new System.IO.MemoryStream(); encoder.Save(imageStream); imageStream.Position = 0; } } return(imageStream); }
public static SaveImageThumbnailResult SaveImageThumbnail(idCatalogItem catalogItem, ref IDImagerDB db, ref IDImagerDB dbThumbs, List<String> types, Boolean keepAspectRatio, Boolean setGenericVideoThumbnailOnError) { SaveImageThumbnailResult result = new SaveImageThumbnailResult(); Stream imageStream = null; String filePath = null; try { filePath = GetImageFilePath(catalogItem); BitmapFrame bitmapFrame; if (ImageFileExtensions.Contains(catalogItem.idFileType)) { imageStream = GetImageFileStream(filePath); bitmapFrame = GetBitmapFrameFromImageStream(imageStream, catalogItem.idFileType); } else if (VideoFileExtensions.Contains(catalogItem.idFileType)) { try { bitmapFrame = BitmapFrame.Create((BitmapSource)GenerateVideoThumbnail(filePath, new TimeSpan(0, 0, 0))); } catch (Exception ex) { if (setGenericVideoThumbnailOnError) { result.Exceptions.Add(new Exception(String.Format("Video thumbnail generation for imageGUID {0} file {1} failed. Generic thumbnails has been set.", catalogItem.GUID, filePath), ex)); Assembly assembly = Assembly.GetExecutingAssembly(); Stream genericVideoThumbnailStream = assembly.GetManifestResourceStream(@"IDBrowserServiceCode.Images.image_ph2.png"); bitmapFrame = BitmapFrame.Create(genericVideoThumbnailStream); } else { result.Exceptions.Add(new Exception(String.Format("Video thumbnail generation for imageGUID {0} file {1} failed.", catalogItem.GUID, filePath), ex)); return result; } } } else { throw new Exception(String.Format("File type {0} not supported", catalogItem.idFileType)); } foreach (String type in types) { int imageWidth; int imageHeight; if (type.Equals("T")) { imageWidth = 160; imageHeight = 120; } else { imageWidth = Int32.Parse(ConfigurationManager.AppSettings["MThumbmailWidth"]); imageHeight = Int32.Parse(ConfigurationManager.AppSettings["MThumbnailHeight"]); } XDocument recipeXDocument = null; if (type.Equals("T") || type.Equals("R")) { if (catalogItem.idHasRecipe > 0) recipeXDocument = GetRecipeXDocument(db, catalogItem); } TransformGroup transformGroup = new TransformGroup(); if (bitmapFrame.PixelWidth > imageWidth && bitmapFrame.PixelHeight > imageHeight) { double scaleX; double scaleY; foreach (ScaleTransform existingScaleTransform in transformGroup.Children.OfType<ScaleTransform>().ToList()) transformGroup.Children.Remove(existingScaleTransform); if (bitmapFrame.PixelWidth > bitmapFrame.PixelHeight) { scaleX = (double)imageWidth / (double)bitmapFrame.PixelWidth; scaleY = (double)imageHeight / (double)bitmapFrame.PixelHeight; } else { scaleX = (double)imageHeight / (double)bitmapFrame.PixelHeight; scaleY = (double)imageWidth / (double)bitmapFrame.PixelWidth; } ScaleTransform scaleTransform = new ScaleTransform(scaleX, scaleY, 0, 0); transformGroup.Children.Add(scaleTransform); } Rotation rotation = StaticFunctions.GetRotation(bitmapFrame); if (rotation != Rotation.Rotate0) { RotateTransform rotateTransform = new RotateTransform(); switch (rotation) { case Rotation.Rotate90: rotateTransform.Angle = 90; break; case Rotation.Rotate180: rotateTransform.Angle = 180; break; case Rotation.Rotate270: rotateTransform.Angle = 270; break; } transformGroup.Children.Add(rotateTransform); } Stream resizedImageStream = imageStream; BitmapSource bitmapSource = bitmapFrame; if (Recipe.ApplyXmpRecipe(recipeXDocument, ref bitmapSource, transformGroup)) { BitmapFrame transformedBitmapFrame = BitmapFrame.Create(bitmapSource); JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(transformedBitmapFrame); resizedImageStream = new System.IO.MemoryStream(); encoder.Save(resizedImageStream); resizedImageStream.Position = 0; } lock (dbThumbs) { idThumbs newThumb = new idThumbs(); newThumb.GUID = Guid.NewGuid().ToString().ToUpper(); newThumb.ImageGUID = catalogItem.GUID; newThumb.idThumb = StreamToByteArray(resizedImageStream); newThumb.idType = type; dbThumbs.idThumbs.Add(newThumb); } result.ImageStreams.Add(resizedImageStream); } if (imageStream != null) { imageStream.Close(); } dbThumbs.SaveChanges(); } catch (Exception ex) { if (imageStream != null) { imageStream.Close(); } result.Exceptions.Add(new Exception(String.Format("Error generating thumbnail for imageGUID {0} file {1}", catalogItem.GUID, filePath), ex)); } return result; }
public async static Task <SaveImageThumbnailResult> SaveImageThumbnail(idCatalogItem catalogItem, IDImagerDB db, IDImagerThumbsDB dbThumbs, List <string> types, ServiceSettings serviceSettings) { SaveImageThumbnailResult result = new SaveImageThumbnailResult(); Stream imageStream = null; String filePath = null; try { filePath = GetImageFilePath(catalogItem, serviceSettings.FilePathReplace); imageStream = GetImageFileStream(filePath); foreach (String type in types) { int imageWidth; int imageHeight; if (type.Equals("T")) { imageWidth = 160; imageHeight = 120; } else { imageWidth = serviceSettings.MThumbmailWidth; imageHeight = serviceSettings.MThumbnailHeight; } XmpRecipeContainer xmpRecipeContainer = null; if (type.Equals("T") || type.Equals("R")) { if (catalogItem.idHasRecipe > 0) { XDocument recipeXDocument = await GetRecipeXDocument(db, catalogItem); xmpRecipeContainer = XmpRecipeHelper.ParseXmlRecepie(recipeXDocument); } } MemoryStream resizedImageStream = new MemoryStream(); MagickReadSettings magickReadSettings = null; if (Enum.TryParse <MagickFormat>(catalogItem.idFileType, true, out MagickFormat magickFormat)) { magickReadSettings = new MagickReadSettings { Format = magickFormat }; } imageStream.Position = 0; MagickImage image = new MagickImage(imageStream, magickReadSettings) { Format = MagickFormat.Jpeg, }; image.Resize(imageWidth, imageHeight); if (xmpRecipeContainer != null) { XmpRecipeHelper.ApplyXmpRecipe(xmpRecipeContainer, image); } image.Write(resizedImageStream); resizedImageStream.Position = 0; bool boolThumbExists = await dbThumbs.idThumbs .AnyAsync(x => x.ImageGUID == catalogItem.GUID && x.idType == type); if (!boolThumbExists) { idThumbs newThumb = new idThumbs { GUID = Guid.NewGuid().ToString().ToUpper(), ImageGUID = catalogItem.GUID, idThumb = StreamToByteArray(resizedImageStream), idType = type }; dbThumbs.idThumbs.Add(newThumb); } result.ImageStreams.Add(resizedImageStream); } if (imageStream != null) { imageStream.Close(); } await dbThumbs.SaveChangesAsync(); } catch (Exception ex) { if (imageStream != null) { imageStream.Close(); } result.Exceptions.Add(new Exception(String.Format("Error generating thumbnail for imageGUID {0} file {1}", catalogItem.GUID, filePath), ex)); } return(result); }