Example #1
0
        private async Task <Tuple <string, DateTime, bool> > GetEnhancedImage(ItemImageInfo image,
                                                                              bool inputImageSupportsTransparency,
                                                                              IHasMetadata item,
                                                                              int imageIndex,
                                                                              List <IImageEnhancer> enhancers,
                                                                              CancellationToken cancellationToken)
        {
            var originalImagePath = image.Path;
            var dateModified      = image.DateModified;
            var imageType         = image.Type;

            try
            {
                var cacheGuid = GetImageCacheTag(item, image, enhancers);

                // Enhance if we have enhancers
                var ehnancedImageInfo = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid, cancellationToken).ConfigureAwait(false);

                var ehnancedImagePath = ehnancedImageInfo.Item1;

                // If the path changed update dateModified
                if (!string.Equals(ehnancedImagePath, originalImagePath, StringComparison.OrdinalIgnoreCase))
                {
                    var treatmentRequiresTransparency = ehnancedImageInfo.Item2;

                    return(new Tuple <string, DateTime, bool>(ehnancedImagePath, _fileSystem.GetLastWriteTimeUtc(ehnancedImagePath), treatmentRequiresTransparency));
                }
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error enhancing image", ex);
            }

            return(new Tuple <string, DateTime, bool>(originalImagePath, dateModified, inputImageSupportsTransparency));
        }
        private ImageInfo GetImageInfo(IHasImages item, ItemImageInfo info, int?imageIndex)
        {
            try
            {
                var fileInfo = new FileInfo(info.Path);

                var size = _imageProcessor.GetImageSize(info.Path);

                return(new ImageInfo
                {
                    Path = info.Path,
                    ImageIndex = imageIndex,
                    ImageType = info.Type,
                    ImageTag = _imageProcessor.GetImageCacheTag(item, info),
                    Size = fileInfo.Length,
                    Width = Convert.ToInt32(size.Width),
                    Height = Convert.ToInt32(size.Height)
                });
            }
            catch (Exception ex)
            {
                Logger.ErrorException("Error getting image information for {0}", ex, info.Path);

                return(null);
            }
        }
Example #3
0
        public async Task <MusicArtist> GetArtistById(int id, CancellationToken cancellationToken)
        {
            var response = await _api.GetArtistById(id, cancellationToken);

            if (response == null)
            {
                return(null);
            }

            var artist = new MusicArtist
            {
                ProviderIds =
                {
                    [VgmdbArtistExternalId.ExternalId] = response.Id.ToString()
                },
                Name = response.name
            };

            var image = new ItemImageInfo
            {
                Path = response.picture_full,
                Type = ImageType.Primary
            };

            artist.SetImage(image, 0);

            artist.Overview = response.notes;

            return(artist);
        }
        /// <summary>
        /// Gets the image cache tag.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="image">The image.</param>
        /// <param name="imageEnhancers">The image enhancers.</param>
        /// <returns>Guid.</returns>
        /// <exception cref="System.ArgumentNullException">item</exception>
        public string GetImageCacheTag(IHasImages item, ItemImageInfo image, List <IImageEnhancer> imageEnhancers)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            if (imageEnhancers == null)
            {
                throw new ArgumentNullException("imageEnhancers");
            }

            if (image == null)
            {
                throw new ArgumentNullException("image");
            }

            var originalImagePath = image.Path;
            var dateModified      = image.DateModified;
            var imageType         = image.Type;

            // Optimization
            if (imageEnhancers.Count == 0)
            {
                return((originalImagePath + dateModified.Ticks).GetMD5().ToString("N"));
            }

            // Cache name is created with supported enhancers combined with the last config change so we pick up new config changes
            var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList();

            cacheKeys.Add(originalImagePath + dateModified.Ticks);

            return(string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N"));
        }
        private async Task <Tuple <string, DateTime> > GetEnhancedImage(ItemImageInfo image,
                                                                        IHasImages item,
                                                                        int imageIndex,
                                                                        List <IImageEnhancer> enhancers)
        {
            var originalImagePath = image.Path;
            var dateModified      = image.DateModified;
            var imageType         = image.Type;

            try
            {
                var cacheGuid = GetImageCacheTag(item, image, enhancers);

                // Enhance if we have enhancers
                var ehnancedImagePath = await GetEnhancedImageInternal(originalImagePath, item, imageType, imageIndex, enhancers, cacheGuid).ConfigureAwait(false);

                // If the path changed update dateModified
                if (!ehnancedImagePath.Equals(originalImagePath, StringComparison.OrdinalIgnoreCase))
                {
                    dateModified = _fileSystem.GetLastWriteTimeUtc(ehnancedImagePath);

                    return(new Tuple <string, DateTime>(ehnancedImagePath, dateModified));
                }
            }
            catch (Exception ex)
            {
                _logger.Error("Error enhancing image", ex);
            }

            return(new Tuple <string, DateTime>(originalImagePath, dateModified));
        }
Example #6
0
        private ImageFormat GetOutputFormat(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List <IImageEnhancer> enhancers)
        {
            if (!string.IsNullOrWhiteSpace(request.Format))
            {
                ImageFormat format;
                if (Enum.TryParse(request.Format, true, out format))
                {
                    return(format);
                }
            }

            var         extension   = Path.GetExtension(image.Path);
            ImageFormat?inputFormat = null;

            if (string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase))
            {
                inputFormat = ImageFormat.Jpg;
            }
            else if (string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase))
            {
                inputFormat = ImageFormat.Png;
            }

            var clientSupportedFormats = GetClientSupportedFormats();

            if (inputFormat.HasValue && clientSupportedFormats.Contains(inputFormat.Value) && enhancers.Count == 0)
            {
                if ((request.Quality ?? 100) == 100 && !request.Height.HasValue && !request.Width.HasValue &&
                    !request.AddPlayedIndicator && !request.PercentPlayed.HasValue && !request.UnplayedCount.HasValue && string.IsNullOrWhiteSpace(request.BackgroundColor))
                {
                    // TODO: Allow this when specfying max width/height if the value is in range
                    if (!cropwhitespace && !request.MaxHeight.HasValue && !request.MaxWidth.HasValue)
                    {
                        return(inputFormat.Value);
                    }
                }
            }

            var serverFormats = _imageProcessor.GetSupportedImageOutputFormats();

            // Client doesn't care about format, so start with webp if supported
            if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp))
            {
                return(ImageFormat.Webp);
            }

            if (enhancers.Count > 0)
            {
                return(ImageFormat.Png);
            }

            if (inputFormat.HasValue && inputFormat.Value == ImageFormat.Jpg)
            {
                return(ImageFormat.Jpg);
            }

            // We can't predict if there will be transparency or not, so play it safe
            return(ImageFormat.Png);
        }
Example #7
0
        public ImageSize GetImageSize(BaseItem item, ItemImageInfo info, bool allowSlowMethods, bool updateItem)
        {
            var width  = info.Width;
            var height = info.Height;

            if (height > 0 && width > 0)
            {
                return(new ImageSize
                {
                    Width = width,
                    Height = height
                });
            }

            var path = info.Path;

            _logger.Info("Getting image size for item {0} {1}", item.GetType().Name, path);

            var size = GetImageSize(path, allowSlowMethods);

            info.Height = Convert.ToInt32(size.Height);
            info.Width  = Convert.ToInt32(size.Width);

            if (updateItem)
            {
                _libraryManager().UpdateImages(item);
            }

            return(size);
        }
Example #8
0
        private ImageFormat GetOutputFormat(ImageRequest request, ItemImageInfo image, List <IImageEnhancer> enhancers)
        {
            if (!string.IsNullOrWhiteSpace(request.Format))
            {
                ImageFormat format;
                if (Enum.TryParse(request.Format, true, out format))
                {
                    return(format);
                }
            }

            var serverFormats = _imageProcessor.GetSupportedImageOutputFormats();

            var clientFormats = GetClientSupportedFormats();

            if (serverFormats.Contains(ImageFormat.Webp) &&
                clientFormats.Contains(ImageFormat.Webp))
            {
                return(ImageFormat.Webp);
            }

            if (enhancers.Count > 0)
            {
                return(ImageFormat.Png);
            }

            if (string.Equals(Path.GetExtension(image.Path), ".jpg", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(Path.GetExtension(image.Path), ".jpeg", StringComparison.OrdinalIgnoreCase))
            {
                return(ImageFormat.Jpg);
            }

            // We can't predict if there will be transparency or not, so play it safe
            return(ImageFormat.Png);
        }
Example #9
0
        protected override bool HasChangedByDate(BaseItem item, ItemImageInfo image)
        {
            if (item is MusicAlbum)
            {
                return(false);
            }

            return(base.HasChangedByDate(item, image));
        }
Example #10
0
        private static string GetImagePathToSave(ItemImageInfo image, ILibraryManager libraryManager, IServerConfigurationManager config)
        {
            if (!image.IsLocalFile)
            {
                return(image.Path);
            }

            return(libraryManager.GetPathAfterNetworkSubstitution(image.Path));
        }
Example #11
0
        private string GetImagePathToSave(ItemImageInfo image, ILibraryManager libraryManager)
        {
            if (!image.IsLocalFile)
            {
                return(image.Path);
            }

            return(libraryManager.GetPathAfterNetworkSubstitution(image.Path));
        }
Example #12
0
        protected virtual bool HasChangedByDate(BaseItem item, ItemImageInfo image)
        {
            var age = DateTime.UtcNow - image.DateModified;

            if (age.TotalDays <= MaxImageAgeDays)
            {
                return(false);
            }
            return(true);
        }
Example #13
0
        private async Task<object> GetImageResult(
            BaseItem item,
            Guid itemId,
            ImageRequest request,
            ItemImageInfo image,
            bool cropwhitespace,
            IReadOnlyCollection<ImageFormat> supportedFormats,
            TimeSpan? cacheDuration,
            IDictionary<string, string> headers,
            bool isHeadRequest)
        {
            if (!image.IsLocalFile)
            {
                item ??= _libraryManager.GetItemById(itemId);
                image = await _libraryManager.ConvertImageToLocal(item, image, request.Index ?? 0).ConfigureAwait(false);
            }

            var options = new ImageProcessingOptions
            {
                CropWhiteSpace = cropwhitespace,
                Height = request.Height,
                ImageIndex = request.Index ?? 0,
                Image = image,
                Item = item,
                ItemId = itemId,
                MaxHeight = request.MaxHeight,
                MaxWidth = request.MaxWidth,
                Quality = request.Quality ?? 100,
                Width = request.Width,
                AddPlayedIndicator = request.AddPlayedIndicator,
                PercentPlayed = request.PercentPlayed ?? 0,
                UnplayedCount = request.UnplayedCount,
                Blur = request.Blur,
                BackgroundColor = request.BackgroundColor,
                ForegroundLayer = request.ForegroundLayer,
                SupportedOutputFormats = supportedFormats
            };

            var imageResult = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);

            headers[HeaderNames.Vary] = HeaderNames.Accept;

            return await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
            {
                CacheDuration = cacheDuration,
                ResponseHeaders = headers,
                ContentType = imageResult.Item2,
                DateLastModified = imageResult.Item3,
                IsHeadRequest = isHeadRequest,
                Path = imageResult.Item1,

                FileShare = FileShare.Read

            }).ConfigureAwait(false);
        }
        public void ItemImageInfoFromValueString_Valid_Success(string value, ItemImageInfo expected)
        {
            var result = _sqliteItemRepository.ItemImageInfoFromValueString(value);

            Assert.Equal(expected.Path, result.Path);
            Assert.Equal(expected.Type, result.Type);
            Assert.Equal(expected.DateModified, result.DateModified);
            Assert.Equal(expected.Width, result.Width);
            Assert.Equal(expected.Height, result.Height);
            Assert.Equal(expected.BlurHash, result.BlurHash);
        }
        public async Task <MusicAlbum> GetAlbumById(int id, CancellationToken cancellationToken)
        {
            var response = await _api.GetAlbumById(id, cancellationToken);

            if (response == null)
            {
                return(null);
            }

            var album = new MusicAlbum
            {
                ProviderIds =
                {
                    [VgmdbAlbumExternalId.ExternalId] = response.Id.ToString()
                },
                Name = response.names.GetPreferred()
            };

            //todo better date parsing
            int.TryParse(response.release_date.Split('-')[0], out var productionYear);
            if (productionYear > 0)
            {
                album.ProductionYear = productionYear;
            }

            var image = new ItemImageInfo
            {
                Path = response.picture_full,
                Type = ImageType.Primary
            };

            album.SetImage(image, 0);

            album.Overview = response.notes;

            if (response.categories != null)
            {
                foreach (var category in response.categories)
                {
                    album.AddGenre(category);
                }
            }

            if (response.organizations != null)
            {
                foreach (var organisation in response.organizations)
                {
                    album.AddStudio(organisation.names.GetPreferred());
                }
            }

            return(album);
        }
Example #16
0
        public UserDto GetUserDto(User user, string remoteEndPoint = null)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            bool hasConfiguredPassword     = GetAuthenticationProvider(user).HasPassword(user).Result;
            bool hasConfiguredEasyPassword = string.IsNullOrEmpty(GetLocalPasswordHash(user));

            bool hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ?
                               hasConfiguredEasyPassword :
                               hasConfiguredPassword;

            UserDto dto = new UserDto
            {
                AccountEmail              = user.AccountEmail,
                Id                        = user.Id,
                Name                      = user.Name,
                HasPassword               = hasPassword,
                HasConfiguredPassword     = hasConfiguredPassword,
                HasConfiguredEasyPassword = hasConfiguredEasyPassword,
                LastActivityDate          = user.LastActivityDate,
                LastLoginDate             = user.LastLoginDate,
                Configuration             = user.Configuration,
                ServerId                  = _appHost.SystemId,
                Policy                    = user.Policy
            };

            if (!hasPassword && Users.Count() == 1)
            {
                dto.EnableAutoLogin = true;
            }

            ItemImageInfo image = user.GetImageInfo(ImageType.Primary, 0);

            if (image != null)
            {
                dto.PrimaryImageTag = GetImageCacheTag(user, image);

                try
                {
                    _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user);
                }
                catch (Exception ex)
                {
                    // Have to use a catch-all unfortunately because some .net image methods throw plain Exceptions
                    _logger.LogError(ex, "Error generating PrimaryImageAspectRatio for {user}", user.Name);
                }
            }

            return(dto);
        }
Example #17
0
 private Guid?GetImageCacheTag(BaseItem item, ItemImageInfo image)
 {
     try
     {
         return(_imageProcessor.GetImageCacheTag(item, image));
     }
     catch (IOException ex)
     {
         _logger.ErrorException("Error getting {0} image info for {1}", ex, image.Type, image.Path);
         return(null);
     }
 }
Example #18
0
 private string GetImageCacheTag(BaseItem item, ItemImageInfo image)
 {
     try
     {
         return(_imageProcessor.GetImageCacheTag(item, image));
     }
     catch (Exception ex)
     {
         _logger.LogError(ex, "Error getting {imageType} image info for {path}", image.Type, image.Path);
         return(null);
     }
 }
Example #19
0
        private List <ImageFormat> GetOutputFormats(ImageRequest request, ItemImageInfo image, bool cropwhitespace, List <IImageEnhancer> enhancers)
        {
            if (!string.IsNullOrWhiteSpace(request.Format))
            {
                ImageFormat format;
                if (Enum.TryParse(request.Format, true, out format))
                {
                    return(new List <ImageFormat> {
                        format
                    });
                }
            }

            var         extension   = Path.GetExtension(image.Path);
            ImageFormat?inputFormat = null;

            if (string.Equals(extension, ".jpg", StringComparison.OrdinalIgnoreCase) ||
                string.Equals(extension, ".jpeg", StringComparison.OrdinalIgnoreCase))
            {
                inputFormat = ImageFormat.Jpg;
            }
            else if (string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase))
            {
                inputFormat = ImageFormat.Png;
            }

            var clientSupportedFormats = GetClientSupportedFormats();

            var serverFormats = _imageProcessor.GetSupportedImageOutputFormats();
            var outputFormats = new List <ImageFormat>();

            // Client doesn't care about format, so start with webp if supported
            if (serverFormats.Contains(ImageFormat.Webp) && clientSupportedFormats.Contains(ImageFormat.Webp))
            {
                outputFormats.Add(ImageFormat.Webp);
            }

            if (enhancers.Count > 0)
            {
                outputFormats.Add(ImageFormat.Png);
            }

            if (inputFormat.HasValue && inputFormat.Value == ImageFormat.Jpg)
            {
                outputFormats.Add(ImageFormat.Jpg);
            }

            // We can't predict if there will be transparency or not, so play it safe
            outputFormats.Add(ImageFormat.Png);

            return(outputFormats);
        }
Example #20
0
        private void GetPrimaryImage(HtmlDocument doc, MetadataResult <Movie> result)
        {
            var frontCoverImg = doc.DocumentNode.SelectSingleNode("//a[@id='front-cover']/img");

            if (frontCoverImg != null && frontCoverImg.HasAttributes && frontCoverImg.Attributes["src"] != null)
            {
                var url = frontCoverImg.Attributes["src"].Value;
                var img = new ItemImageInfo();
                img.Type = ImageType.Primary;
                img.Path = url;
                result.Item.ImageInfos.Add(img);
            }
        }
Example #21
0
        private ImageInfo GetImageInfo(BaseItem item, ItemImageInfo info, int? imageIndex)
        {
            int? width = null;
            int? height = null;
            string blurhash = null;
            long length = 0;

            try
            {
                if (info.IsLocalFile)
                {
                    var fileInfo = _fileSystem.GetFileInfo(info.Path);
                    length = fileInfo.Length;

                    blurhash = info.BlurHash;
                    width = info.Width;
                    height = info.Height;

                    if (width <= 0 || height <= 0)
                    {
                        width = null;
                        height = null;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Error getting image information for {Item}", item.Name);
            }

            try
            {
                return new ImageInfo
                {
                    Path = info.Path,
                    ImageIndex = imageIndex,
                    ImageType = info.Type,
                    ImageTag = _imageProcessor.GetImageCacheTag(item, info),
                    Size = length,
                    BlurHash = blurhash,
                    Width = width,
                    Height = height
                };
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Error getting image information for {Path}", info.Path);

                return null;
            }
        }
Example #22
0
        private async Task <object> GetImageResult(IHasImages item,
                                                   ImageRequest request,
                                                   ItemImageInfo image,
                                                   bool cropwhitespace,
                                                   List <ImageFormat> supportedFormats,
                                                   List <IImageEnhancer> enhancers,
                                                   TimeSpan?cacheDuration,
                                                   IDictionary <string, string> headers,
                                                   bool isHeadRequest)
        {
            var options = new ImageProcessingOptions
            {
                CropWhiteSpace         = cropwhitespace,
                Enhancers              = enhancers,
                Height                 = request.Height,
                ImageIndex             = request.Index ?? 0,
                Image                  = image,
                Item                   = item,
                ItemId                 = item.Id.ToString("N"),
                ItemType               = item.GetType().Name,
                MaxHeight              = request.MaxHeight,
                MaxWidth               = request.MaxWidth,
                Quality                = request.Quality ?? 100,
                Width                  = request.Width,
                AddPlayedIndicator     = request.AddPlayedIndicator,
                PercentPlayed          = request.PercentPlayed ?? 0,
                UnplayedCount          = request.UnplayedCount,
                Blur                   = request.Blur,
                BackgroundColor        = request.BackgroundColor,
                ForegroundLayer        = request.ForegroundLayer,
                SupportedOutputFormats = supportedFormats
            };

            var imageResult = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);

            headers["Vary"] = "Accept";

            return(await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
            {
                CacheDuration = cacheDuration,
                ResponseHeaders = headers,
                ContentType = imageResult.Item2,
                DateLastModified = imageResult.Item3,
                IsHeadRequest = isHeadRequest,
                Path = imageResult.Item1,

                // Sometimes imagemagick keeps a hold on the file briefly even after it's done writing to it.
                // I'd rather do this than add a delay after saving the file
                FileShare = FileShareMode.ReadWrite
            }).ConfigureAwait(false));
        }
Example #23
0
        private ImageInfo GetImageInfo(BaseItem item, ItemImageInfo info, int?imageIndex)
        {
            int? width  = null;
            int? height = null;
            long length = 0;

            try
            {
                if (info.IsLocalFile)
                {
                    var fileInfo = _fileSystem.GetFileInfo(info.Path);
                    length = fileInfo.Length;

                    ImageDimensions size = _imageProcessor.GetImageDimensions(item, info);
                    _libraryManager.UpdateImages(item);
                    width  = size.Width;
                    height = size.Height;

                    if (width <= 0 || height <= 0)
                    {
                        width  = null;
                        height = null;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Error getting image information for {Item}", item.Name);
            }

            try
            {
                return(new ImageInfo
                {
                    Path = info.Path,
                    ImageIndex = imageIndex,
                    ImageType = info.Type,
                    ImageTag = _imageProcessor.GetImageCacheTag(item, info),
                    Size = length,
                    Width = width,
                    Height = height
                });
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Error getting image information for {Path}", info.Path);

                return(null);
            }
        }
Example #24
0
        private async Task <object> GetImageResult(BaseItem item,
                                                   Guid itemId,
                                                   ImageRequest request,
                                                   ItemImageInfo image,
                                                   bool cropwhitespace,
                                                   ImageFormat[] supportedFormats,
                                                   IImageEnhancer[] enhancers,
                                                   TimeSpan?cacheDuration,
                                                   IDictionary <string, string> headers,
                                                   bool isHeadRequest)
        {
            var options = new ImageProcessingOptions
            {
                CropWhiteSpace         = cropwhitespace,
                Enhancers              = enhancers,
                Height                 = request.Height,
                ImageIndex             = request.Index ?? 0,
                Image                  = image,
                Item                   = item,
                ItemId                 = itemId,
                MaxHeight              = request.MaxHeight,
                MaxWidth               = request.MaxWidth,
                Quality                = request.Quality ?? 100,
                Width                  = request.Width,
                AddPlayedIndicator     = request.AddPlayedIndicator,
                PercentPlayed          = request.PercentPlayed ?? 0,
                UnplayedCount          = request.UnplayedCount,
                Blur                   = request.Blur,
                BackgroundColor        = request.BackgroundColor,
                ForegroundLayer        = request.ForegroundLayer,
                SupportedOutputFormats = supportedFormats
            };

            var imageResult = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);

            headers["Vary"] = "Accept";

            return(await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
            {
                CacheDuration = cacheDuration,
                ResponseHeaders = headers,
                ContentType = imageResult.Item2,
                DateLastModified = imageResult.Item3,
                IsHeadRequest = isHeadRequest,
                Path = imageResult.Item1,

                FileShare = FileShareMode.Read
            }).ConfigureAwait(false));
        }
Example #25
0
        private async Task <object> GetImageResult(IHasImages item,
                                                   ImageRequest request,
                                                   ItemImageInfo image,
                                                   ImageFormat format,
                                                   List <IImageEnhancer> enhancers,
                                                   string contentType,
                                                   TimeSpan?cacheDuration,
                                                   IDictionary <string, string> headers,
                                                   bool isHeadRequest)
        {
            var cropwhitespace = request.Type == ImageType.Logo || request.Type == ImageType.Art;

            if (request.CropWhitespace.HasValue)
            {
                cropwhitespace = request.CropWhitespace.Value;
            }

            var options = new ImageProcessingOptions
            {
                CropWhiteSpace     = cropwhitespace,
                Enhancers          = enhancers,
                Height             = request.Height,
                ImageIndex         = request.Index ?? 0,
                Image              = image,
                Item               = item,
                MaxHeight          = request.MaxHeight,
                MaxWidth           = request.MaxWidth,
                Quality            = request.Quality,
                Width              = request.Width,
                AddPlayedIndicator = request.AddPlayedIndicator,
                PercentPlayed      = request.PercentPlayed ?? 0,
                UnplayedCount      = request.UnplayedCount,
                BackgroundColor    = request.BackgroundColor,
                OutputFormat       = format
            };

            var file = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);

            headers["Vary"] = "Accept";

            return(ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
            {
                CacheDuration = cacheDuration,
                ResponseHeaders = headers,
                ContentType = contentType,
                IsHeadRequest = isHeadRequest,
                Path = file
            }));
        }
Example #26
0
        private ImageInfo GetImageInfo(BaseItem item, ItemImageInfo info, int?imageIndex)
        {
            try
            {
                int? width  = null;
                int? height = null;
                long length = 0;

                try
                {
                    if (info.IsLocalFile)
                    {
                        var fileInfo = _fileSystem.GetFileInfo(info.Path);
                        length = fileInfo.Length;

                        var size = _imageProcessor.GetImageSize(item, info, true, true);

                        width  = Convert.ToInt32(size.Width);
                        height = Convert.ToInt32(size.Height);

                        if (width <= 0 || height <= 0)
                        {
                            width  = null;
                            height = null;
                        }
                    }
                }
                catch
                {
                }
                return(new ImageInfo
                {
                    Path = info.Path,
                    ImageIndex = imageIndex,
                    ImageType = info.Type,
                    ImageTag = _imageProcessor.GetImageCacheTag(item, info),
                    Size = length,
                    Width = width,
                    Height = height
                });
            }
            catch (Exception ex)
            {
                Logger.ErrorException("Error getting image information for {0}", ex, info.Path);

                return(null);
            }
        }
        /// <summary>
        /// Gets the image cache tag.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="image">The image.</param>
        /// <returns>Guid.</returns>
        /// <exception cref="System.ArgumentNullException">item</exception>
        public string GetImageCacheTag(IHasImages item, ItemImageInfo image)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            if (image == null)
            {
                throw new ArgumentNullException("image");
            }

            var supportedEnhancers = GetSupportedEnhancers(item, image.Type);

            return(GetImageCacheTag(item, image, supportedEnhancers.ToList()));
        }
Example #28
0
        private async Task <object> GetImageResult(
            Guid itemId,
            ImageRequest request,
            ItemImageInfo info,
            IReadOnlyCollection <ImageFormat> supportedFormats,
            TimeSpan?cacheDuration,
            IDictionary <string, string> headers,
            bool isHeadRequest)
        {
            info.Type = ImageType.Profile;
            var options = new ImageProcessingOptions
            {
                CropWhiteSpace         = true,
                Height                 = request.Height,
                ImageIndex             = request.Index ?? 0,
                Image                  = info,
                Item                   = null, // Hack alert
                ItemId                 = itemId,
                MaxHeight              = request.MaxHeight,
                MaxWidth               = request.MaxWidth,
                Quality                = request.Quality ?? 100,
                Width                  = request.Width,
                AddPlayedIndicator     = request.AddPlayedIndicator,
                PercentPlayed          = 0,
                UnplayedCount          = request.UnplayedCount,
                Blur                   = request.Blur,
                BackgroundColor        = request.BackgroundColor,
                ForegroundLayer        = request.ForegroundLayer,
                SupportedOutputFormats = supportedFormats
            };

            var imageResult = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);

            headers[HeaderNames.Vary] = HeaderNames.Accept;

            return(await ResultFactory.GetStaticFileResult(Request, new StaticFileResultOptions
            {
                CacheDuration = cacheDuration,
                ResponseHeaders = headers,
                ContentType = imageResult.Item2,
                DateLastModified = imageResult.Item3,
                IsHeadRequest = isHeadRequest,
                Path = imageResult.Item1,

                FileShare = FileShare.Read
            }).ConfigureAwait(false));
        }
Example #29
0
        /// <summary>
        /// Gets the image cache tag.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="image">The image.</param>
        /// <param name="imageEnhancers">The image enhancers.</param>
        /// <returns>Guid.</returns>
        /// <exception cref="System.ArgumentNullException">item</exception>
        public string GetImageCacheTag(BaseItem item, ItemImageInfo image, IImageEnhancer[] imageEnhancers)
        {
            var originalImagePath = image.Path;
            var dateModified      = image.DateModified;
            var imageType         = image.Type;

            // Optimization
            if (imageEnhancers.Length == 0)
            {
                return((originalImagePath + dateModified.Ticks).GetMD5().ToString("N"));
            }

            // Cache name is created with supported enhancers combined with the last config change so we pick up new config changes
            var cacheKeys = imageEnhancers.Select(i => i.GetConfigurationCacheKey(item, imageType)).ToList();

            cacheKeys.Add(originalImagePath + dateModified.Ticks);

            return(string.Join("|", cacheKeys.ToArray()).GetMD5().ToString("N"));
        }
Example #30
0
        private string GetTagAndFillBlurhash(BaseItemDto dto, BaseItem item, ItemImageInfo image)
        {
            var tag = GetImageCacheTag(item, image);

            if (!string.IsNullOrEmpty(image.BlurHash))
            {
                if (dto.ImageBlurHashes == null)
                {
                    dto.ImageBlurHashes = new Dictionary <ImageType, Dictionary <string, string> >();
                }

                if (!dto.ImageBlurHashes.ContainsKey(image.Type))
                {
                    dto.ImageBlurHashes[image.Type] = new Dictionary <string, string>();
                }

                dto.ImageBlurHashes[image.Type][tag] = image.BlurHash;
            }

            return(tag);
        }