private static String GetCatalogItemFilePath(String guid)
        {
            IDImagerDB    db          = new IDImagerDB();
            idCatalogItem catalogItem = db.idCatalogItem.Include("idFilePath").Single(x => x.GUID.Equals(guid));

            db.Dispose();
            return(StaticFunctions.GetImageFilePath(catalogItem));
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Controller constructor
 /// </summary>
 /// <param name="db">IDImagerDB</param>
 /// <param name="serviceSettings">ServiceSettings</param>
 /// <param name="logger">Logger</param>
 /// <param name="diagnosticContext">Logger diagnostic context</param>
 public MediaController(IDImagerDB db, ServiceSettings serviceSettings,
                        ILogger <MediaController> logger, IDiagnosticContext diagnosticContext)
 {
     this.db = db ?? throw new ArgumentNullException(nameof(logger));
     this.serviceSettings   = serviceSettings ?? throw new ArgumentNullException(nameof(serviceSettings));
     this.logger            = logger ?? throw new ArgumentNullException(nameof(logger));
     this.diagnosticContext = diagnosticContext ?? throw new ArgumentNullException(nameof(diagnosticContext));
 }
        public static System.Xml.Linq.XDocument GetRecipeXDocument(IDImagerDB db, idCatalogItem catalogItem)
        {
            if (catalogItem.idHasRecipe > 0)
            {
                idImageData imageData = db.idImageData.SingleOrDefault(x => x.ImageGUID.Equals(catalogItem.GUID) && x.DataName.Equals("XMP"));

                if (imageData != null)
                {
                    MemoryStream compressedXmpStream = new MemoryStream(imageData.idData);
                    MemoryStream decompressedXmpStream = new MemoryStream();
                    ZOutputStream outZStream = new ZOutputStream(decompressedXmpStream);

                    compressedXmpStream.CopyTo(outZStream);
                    decompressedXmpStream.Position = 0;
                    System.Xml.Linq.XDocument xdocument = System.Xml.Linq.XDocument.Load(decompressedXmpStream);
                    compressedXmpStream.Close();
                    decompressedXmpStream.Close();

                    return xdocument;
                }
            }

            return null;
        }
        public async static Task <XDocument> GetRecipeXDocument(IDImagerDB db, idCatalogItem catalogItem)
        {
            if (catalogItem.idHasRecipe > 0)
            {
                idImageData imageData = await db.idImageData.SingleOrDefaultAsync(x => x.ImageGUID.Equals(catalogItem.GUID) && x.DataName.Equals("XMP"));

                if (imageData != null)
                {
                    MemoryStream  compressedXmpStream   = new MemoryStream(imageData.idData);
                    MemoryStream  decompressedXmpStream = new MemoryStream();
                    ZOutputStream outZStream            = new ZOutputStream(decompressedXmpStream);

                    compressedXmpStream.CopyTo(outZStream);
                    decompressedXmpStream.Position = 0;
                    XDocument xdocument = XDocument.Load(decompressedXmpStream);
                    compressedXmpStream.Close();
                    decompressedXmpStream.Close();

                    return(xdocument);
                }
            }

            return(null);
        }
        /// <summary>
        /// Transcode's all videos of a site
        /// </summary>
        /// <param name="configuration">Json configuration of IDBrowserService as IDBrowserConfiguration class</param>
        /// <param name="cancellationToken">CancellationToken</param>
        /// <param name="siteName">Site name to transcode</param>
        /// <param name="videoSize">Video size to transcode. (e.g. Hd480, Hd720, Hd1080)</param>
        /// <param name="taskCount">FFmpeg task count (Default 2)</param>
        /// <param name="logLevel">Serilog log level</param>
        public static void TranscodeAllVideos(IDBrowserConfiguration configuration, CancellationToken cancellationToken,
                                              string siteName, string videoSize, Serilog.Events.LogEventLevel logLevel, int taskCount)
        {
            LoggingLevelSwitch loggingLevelSwitch = new LoggingLevelSwitch
            {
                MinimumLevel = logLevel
            };

            Log.Logger = new LoggerConfiguration()
                         .MinimumLevel.ControlledBy(loggingLevelSwitch)
                         .WriteTo.File(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Log", "ConsoleFunctions.log"))
                         .CreateLogger();

            SiteSettings siteSettings = configuration.Sites[siteName];

            IDImagerDB db = new IDImagerDB(GetIDImagerDBOptionsBuilder <IDImagerDB>(siteSettings.ConnectionStrings.DBType,
                                                                                    siteSettings.ConnectionStrings.IDImager).Options);

            var query = db.idCatalogItem
                        .Include(x => x.idFilePath)
                        .Where(x => configuration.VideoFileExtensions.Contains(x.idFileType));

            ProgressTaskFactory progressTaskFactory = new ProgressTaskFactory(taskCount, 100, 60, Log.Logger);

            Task windowChangeListenerTask = new Task(() =>
            {
                int width  = Console.WindowWidth;
                int height = Console.WindowHeight;

                while (!cancellationToken.IsCancellationRequested)
                {
                    if (width != Console.WindowWidth || height != Console.WindowHeight)
                    {
                        width  = Console.WindowWidth;
                        height = Console.WindowHeight;

                        progressTaskFactory.RedrawConsoleWindows(100, 60);
                    }

                    cancellationToken.WaitHandle.WaitOne(100);
                }
            }, cancellationToken);

            windowChangeListenerTask.Start();

            if (!IsWindows)
            {
                // Log output scrolling not supported at the moment because Console.MoveBufferArea is currently not supported under Linux and MacOs.
                // But we can write a single infoline.
                progressTaskFactory.WriteLog("Log output in console not supported under Linux at the moment. Please take a look at the ConsoleFunctions.log in Logs directory.",
                                             true, LogEventLevel.Information);
            }

            List <TranscodeVideoBatchInfo> listTranscodeVideoBatch = new List <TranscodeVideoBatchInfo>();

            foreach (idCatalogItem catalogItem in query)
            {
                catalogItem.GetHeightAndWidth(out int originalVideoWidth, out int originalVideoHeight);

                string strTranscodeFilePath = StaticFunctions.GetTranscodeFilePath(catalogItem.GUID,
                                                                                   siteSettings.ServiceSettings.TranscodeDirectory, videoSize);
                FileInfo transcodeFileInfo = new FileInfo(strTranscodeFilePath);

                if (!transcodeFileInfo.Exists)
                {
                    string strOriginalFilePath = StaticFunctions.GetImageFilePath(catalogItem, siteSettings.ServiceSettings.FilePathReplace);

                    TranscodeVideoBatchInfo transcodeVideoBatchInfo = new TranscodeVideoBatchInfo(catalogItem.GUID, originalVideoWidth, originalVideoHeight,
                                                                                                  strOriginalFilePath, strTranscodeFilePath);

                    listTranscodeVideoBatch.Add(transcodeVideoBatchInfo);
                }
            }

            db.Dispose();

            int intTotalCount = listTranscodeVideoBatch.Count();
            int intCounter    = 1;
            TranscodeVideoBatchInfo lastTranscodeVideoBatch = listTranscodeVideoBatch.LastOrDefault();

            foreach (TranscodeVideoBatchInfo transcodeVideoBatchInfo in listTranscodeVideoBatch)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                string strTranscodeFilePath = StaticFunctions.GetTranscodeFilePath(transcodeVideoBatchInfo.GUID,
                                                                                   siteSettings.ServiceSettings.TranscodeDirectory, videoSize);

                StaticFunctions.GetTranscodeVideoSize(videoSize, transcodeVideoBatchInfo.VideoWidth, transcodeVideoBatchInfo.VideoHeight,
                                                      out VideoSize targetVideoSize, out int targetVideoWidth, out int targetVideoHeight);

                var conversionOptions = StaticFunctions.GetConversionOptions(targetVideoSize, transcodeVideoBatchInfo.VideoWidth,
                                                                             transcodeVideoBatchInfo.VideoHeight);

                progressTaskFactory.WriteLog(string.Format("Transcoding file {0} of {1} with guid {2} and path \"{3}\" from resolution {4}x{5} to {6}x{7} ",
                                                           intCounter, intTotalCount, transcodeVideoBatchInfo.GUID, transcodeVideoBatchInfo.VideoFileInfo.FullName, transcodeVideoBatchInfo.VideoWidth,
                                                           transcodeVideoBatchInfo.VideoHeight, targetVideoWidth, targetVideoHeight),
                                             IsWindows, LogEventLevel.Information);

                ProgressTask progressTask = progressTaskFactory.GetIdleProgressTask();

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                if (progressTask == null)
                {
                    progressTask = progressTaskFactory
                                   .WaitForAnyTask()
                                   .Result;
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                string progressBarText = string.Format("{0} ({1} of {2})", transcodeVideoBatchInfo.TranscodeFileInfo.Name, intCounter, intTotalCount);

                progressTask.Task = new Task(() => {
                    TranscodeVideoProgressTask(transcodeVideoBatchInfo, videoSize, cancellationToken, progressTask, progressBarText);
                });

                progressTask.Task.Start();

                // If we are on the last item we have to wait for all tasks to complete
                if (transcodeVideoBatchInfo == lastTranscodeVideoBatch)
                {
                    progressTaskFactory.WaitForAllTasks();
                }

                intCounter++;
            }

            Log.CloseAndFlush();
        }
        /// <summary>
        /// Generates thumbnails based on parameters
        /// </summary>
        /// <param name="configuration">Json configuration of IDBrowserService as IDBrowserConfiguration class</param>
        /// <param name="siteName">Site name to generate thumbnails</param>
        /// <param name="fromDateTime">From date filter</param>
        /// <param name="toDateTime">To date filter</param>
        /// <param name="fileFilter">File type filter</param>
        /// <param name="imageGuid">Generate single image guid</param>
        /// <param name="overwrite">Overwrite existing thumbnails</param>
        public async static void GenerateThumbnails(IDBrowserConfiguration configuration, string siteName, DateTime fromDateTime,
                                                    DateTime toDateTime, string fileFilter, string imageGuid, bool overwrite)
        {
            SiteSettings siteSettings = configuration.Sites[siteName];

            var optionsBuilder = new DbContextOptionsBuilder <IDImagerDB>();

            if (siteSettings.ConnectionStrings.DBType.Equals("MsSql"))
            {
                optionsBuilder.UseSqlServer(siteSettings.ConnectionStrings.IDImager);
            }
            else if (siteSettings.ConnectionStrings.DBType.Equals("Postgres"))
            {
                optionsBuilder.UseNpgsql(siteSettings.ConnectionStrings.IDImager);
                optionsBuilder.ReplaceService <ISqlGenerationHelper, PostgresSqlGenerationHelper>();
            }

            IDImagerDB db = new IDImagerDB(GetIDImagerDBOptionsBuilder <IDImagerDB>(siteSettings.ConnectionStrings.DBType,
                                                                                    siteSettings.ConnectionStrings.IDImager).Options);
            IDImagerThumbsDB dbThumbs = new IDImagerThumbsDB(GetIDImagerDBOptionsBuilder <IDImagerThumbsDB>(siteSettings.ConnectionStrings.DBType,
                                                                                                            siteSettings.ConnectionStrings.IDImagerThumbs).Options);

            var queryCatalogItem = from catalogItem in db.idCatalogItem.Include("idFilePath")
                                   where configuration.ImageFileExtensions.Contains(catalogItem.idFileType) ||
                                   configuration.VideoFileExtensions.Contains(catalogItem.idFileType)
                                   select catalogItem;

            if (fromDateTime != DateTime.MinValue)
            {
                queryCatalogItem = queryCatalogItem.Where(x => x.idCreated >= fromDateTime);
            }

            if (toDateTime != DateTime.MinValue)
            {
                queryCatalogItem = queryCatalogItem.Where(x => x.idCreated <= toDateTime);
            }

            if (!string.IsNullOrEmpty(fileFilter))
            {
                queryCatalogItem = queryCatalogItem.Where(x => x.idFileType.ToLower().Equals(fileFilter.ToLower()));
            }

            if (!string.IsNullOrEmpty(imageGuid))
            {
                queryCatalogItem = queryCatalogItem.Where(x => x.GUID.Equals(imageGuid, StringComparison.OrdinalIgnoreCase));
            }

            int intCountCatalogItem    = queryCatalogItem.Count();
            int intCatalogItemCounter  = 0;
            int intThumbnailsGenerated = 0;

            foreach (idCatalogItem catalogItem in queryCatalogItem)
            {
                List <String>   typesToGenerate = new List <String>();
                List <idThumbs> idThumbsT       = dbThumbs.idThumbs.Where(x => x.ImageGUID == catalogItem.GUID && x.idType.Equals("T")).ToList();
                List <idThumbs> idThumbsM       = dbThumbs.idThumbs.Where(x => x.ImageGUID == catalogItem.GUID && x.idType.Equals("M")).ToList();
                List <idThumbs> idThumbsR       = dbThumbs.idThumbs.Where(x => x.ImageGUID == catalogItem.GUID && x.idType.Equals("R")).ToList();

                if (idThumbsT.Count() == 0)
                {
                    typesToGenerate.Add("T");
                }

                if (idThumbsM.Count() == 0)
                {
                    typesToGenerate.Add("M");
                }

                if (catalogItem.idHasRecipe > 0 && idThumbsR.Count() == 0)
                {
                    typesToGenerate.Add("R");
                }

                if (overwrite)
                {
                    foreach (idThumbs thumb in idThumbsT)
                    {
                        dbThumbs.idThumbs.Remove(thumb);
                    }

                    foreach (idThumbs thumb in idThumbsM)
                    {
                        dbThumbs.idThumbs.Remove(thumb);
                    }

                    foreach (idThumbs thumb in idThumbsR)
                    {
                        dbThumbs.idThumbs.Remove(thumb);
                    }

                    typesToGenerate.Clear();
                    typesToGenerate.Add("T");
                    typesToGenerate.Add("M");
                    if (catalogItem.idHasRecipe > 0)
                    {
                        typesToGenerate.Add("R");
                    }
                }

                if (typesToGenerate.Count() > 0)
                {
                    try
                    {
                        SaveImageThumbnailResult result = await StaticFunctions.SaveImageThumbnail(catalogItem, db, dbThumbs, typesToGenerate,
                                                                                                   siteSettings.ServiceSettings);

                        foreach (Exception ex in result.Exceptions)
                        {
                            LogGenerateThumbnailsException(ex);
                            Console.WriteLine(ex.ToString());
                        }

                        if (result.Exceptions.Count > 0)
                        {
                            LogGenerateThumbnailsFailedCatalogItem(catalogItem);
                        }

                        intThumbnailsGenerated += result.ImageStreams.Count();
                    }
                    catch (Exception e)
                    {
                        LogGenerateThumbnailsException(e);
                        LogGenerateThumbnailsFailedCatalogItem(catalogItem);
                        Console.WriteLine(e.ToString());
                    }
                }

                intCatalogItemCounter += 1;

                Console.CursorLeft = 0;
                Console.Write(String.Format("{0} of {1} catalogitems checked. {2} thumbnails generated", intCatalogItemCounter, intCountCatalogItem, intThumbnailsGenerated));
            }
        }
Ejemplo n.º 7
0
        //private static void GenerateThumbnails(String type)
        //{
        //    Boolean keepAspectRatio = Boolean.Parse(ConfigurationManager.AppSettings["KeepAspectRatio"]);
        //    Boolean setGenericVideoThumbnailOnError = Boolean.Parse(ConfigurationManager.AppSettings["SetGenericVideoThumbnailOnError"]);

        //    IDImagerEntities db = new IDBrowserServiceCode.IDImagerEntities();
        //    IDImagerEntities dbThumbs = new IDBrowserServiceCode.IDImagerEntities(ConfigurationManager.ConnectionStrings["IDImagerThumbsEntities"].ConnectionString);

        //    List<String> imageFileExtensions = ConfigurationManager.AppSettings["ImageFileExtensions"].Split(new char[] {char.Parse(",")}).ToList();
        //    List<String> videoFileExtensions = ConfigurationManager.AppSettings["VideoFileExtensions"].Split(new char[] { char.Parse(",") }).ToList();

        //    List<String> thumbImageGuids = dbThumbs.idThumbs.Where(x => x.idType.Equals(type)).Select(x => x.ImageGUID).ToList();

        //    Console.WriteLine("Getting images without thumbnails....");
        //    var queryThumbnails = from catalogItem in db.idCatalogItem.Include("idFilePath")
        //                          where !thumbImageGuids.Contains(catalogItem.GUID) && (imageFileExtensions.Contains(catalogItem.idFileType) || videoFileExtensions.Contains(catalogItem.idFileType))
        //                          select catalogItem;

        //    int intCountCatalogItem = queryThumbnails.Count();
        //    int intCatalogItemCounter = 0;

        //    foreach (idCatalogItem catalogItem in queryThumbnails)
        //    {
        //        try
        //        {
        //            SaveImageThumbnailResult result = StaticFunctions.SaveImageThumbnail(catalogItem, ref db, ref dbThumbs, new List<String>() { type }, keepAspectRatio, setGenericVideoThumbnailOnError);
        //            foreach (Exception ex in result.Exceptions)
        //            {
        //                LogException(ex);
        //                Console.WriteLine(ex.ToString());
        //            }

        //            if (result.Exceptions.Count > 0)
        //            {
        //                LogFailedCatalogItem(catalogItem);
        //            }
        //        }
        //        catch (Exception ex)
        //        {
        //            LogException(ex);
        //            LogFailedCatalogItem(catalogItem);
        //            Console.WriteLine(ex.ToString());
        //        }

        //        intCatalogItemCounter += 1;
        //        Console.CursorLeft = 0;
        //        Console.Write(String.Format("{0} of {1} T thumbnails generated", intCatalogItemCounter, intCountCatalogItem));
        //    }
        //}

        private static void GenerateThumbnails()
        {
            Boolean keepAspectRatio = Boolean.Parse(ConfigurationManager.AppSettings["KeepAspectRatio"]);
            Boolean setGenericVideoThumbnailOnError = Boolean.Parse(ConfigurationManager.AppSettings["SetGenericVideoThumbnailOnError"]);

            var commandLineArguments  = new CommandLineArguments();
            ICommandLineParser parser = new CommandLineParser();

            parser.ParseArguments(Environment.GetCommandLineArgs(), commandLineArguments);

            IDImagerDB db       = new IDImagerDB();
            IDImagerDB dbThumbs = new IDImagerDB();

            dbThumbs.Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["IDImagerThumbsEntities"].ConnectionString;

            List <String> imageFileExtensions = ConfigurationManager.AppSettings["ImageFileExtensions"].Split(new char[] { char.Parse(",") }).ToList();
            List <String> videoFileExtensions = ConfigurationManager.AppSettings["VideoFileExtensions"].Split(new char[] { char.Parse(",") }).ToList();

            var queryCatalogItem = from catalogItem in db.idCatalogItem.Include("idFilePath")
                                   where imageFileExtensions.Contains(catalogItem.idFileType) || videoFileExtensions.Contains(catalogItem.idFileType)
                                   select catalogItem;

            if (commandLineArguments.FromDateTime != DateTime.MinValue)
            {
                queryCatalogItem = queryCatalogItem.Where(x => x.idCreated >= commandLineArguments.FromDateTime);
            }

            if (commandLineArguments.ToDateTime != DateTime.MinValue)
            {
                queryCatalogItem = queryCatalogItem.Where(x => x.idCreated <= commandLineArguments.ToDateTime);
            }

            if (commandLineArguments.FileFilter != null)
            {
                queryCatalogItem = queryCatalogItem.Where(x => x.idFileType.ToLower().Equals(commandLineArguments.FileFilter.ToLower()));
            }

            if (commandLineArguments.ImageGuid != null)
            {
                queryCatalogItem = queryCatalogItem.Where(x => x.GUID.Equals(commandLineArguments.ImageGuid, StringComparison.OrdinalIgnoreCase));
            }

            int intCountCatalogItem    = queryCatalogItem.Count();
            int intCatalogItemCounter  = 0;
            int intThumbnailsGenerated = 0;

            foreach (idCatalogItem catalogItem in queryCatalogItem)
            {
                List <String>   typesToGenerate = new List <String>();
                List <idThumbs> idThumbsT       = dbThumbs.idThumbs.Where(x => x.ImageGUID == catalogItem.GUID && x.idType.Equals("T")).ToList();
                List <idThumbs> idThumbsM       = dbThumbs.idThumbs.Where(x => x.ImageGUID == catalogItem.GUID && x.idType.Equals("M")).ToList();
                List <idThumbs> idThumbsR       = dbThumbs.idThumbs.Where(x => x.ImageGUID == catalogItem.GUID && x.idType.Equals("R")).ToList();

                if (idThumbsT.Count() == 0)
                {
                    typesToGenerate.Add("T");
                }

                if (idThumbsM.Count() == 0)
                {
                    typesToGenerate.Add("M");
                }

                if (catalogItem.idHasRecipe > 0 && idThumbsR.Count() == 0)
                {
                    typesToGenerate.Add("R");
                }

                if (commandLineArguments.Overwrite)
                {
                    foreach (idThumbs thumb in idThumbsT)
                    {
                        dbThumbs.idThumbs.Remove(thumb);
                    }

                    foreach (idThumbs thumb in idThumbsM)
                    {
                        dbThumbs.idThumbs.Remove(thumb);
                    }

                    foreach (idThumbs thumb in idThumbsR)
                    {
                        dbThumbs.idThumbs.Remove(thumb);
                    }

                    typesToGenerate.Clear();
                    typesToGenerate.Add("T");
                    typesToGenerate.Add("M");
                    if (catalogItem.idHasRecipe > 0)
                    {
                        typesToGenerate.Add("R");
                    }
                }

                if (typesToGenerate.Count() > 0)
                {
                    try
                    {
                        SaveImageThumbnailResult result = StaticFunctions.SaveImageThumbnail(catalogItem, ref db, ref dbThumbs, typesToGenerate, keepAspectRatio, setGenericVideoThumbnailOnError);
                        foreach (Exception ex in result.Exceptions)
                        {
                            LogException(ex);
                            Console.WriteLine(ex.ToString());
                        }

                        if (result.Exceptions.Count > 0)
                        {
                            LogFailedCatalogItem(catalogItem);
                        }

                        intThumbnailsGenerated += result.ImageStreams.Count();
                    }
                    catch (Exception e)
                    {
                        LogException(e);
                        LogFailedCatalogItem(catalogItem);
                        Console.WriteLine(e.ToString());
                    }
                }

                intCatalogItemCounter += 1;

                Console.CursorLeft = 0;
                Console.Write(String.Format("{0} of {1} catalogitems checked. {2} thumbnails generated", intCatalogItemCounter, intCountCatalogItem, intThumbnailsGenerated));
            }
        }
        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);
        }