Ejemplo n.º 1
0
        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);
        }