aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Emby.Drawing.ImageMagick/ImageMagickEncoder.cs18
-rw-r--r--Emby.Drawing.Skia/SkiaEncoder.cs39
-rw-r--r--Emby.Drawing/ImageProcessor.cs84
-rw-r--r--Emby.Drawing/NullImageEncoder.cs2
-rw-r--r--Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs8
-rw-r--r--MediaBrowser.Controller/Drawing/IImageEncoder.cs2
-rw-r--r--MediaBrowser.Controller/Drawing/IImageProcessor.cs2
-rw-r--r--MediaBrowser.Controller/Drawing/ImageHelper.cs10
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs16
9 files changed, 139 insertions, 42 deletions
diff --git a/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs b/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs
index 13bde3ca5..4c911cc7a 100644
--- a/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs
+++ b/Emby.Drawing.ImageMagick/ImageMagickEncoder.cs
@@ -130,7 +130,7 @@ namespace Emby.Drawing.ImageMagick
string.Equals(ext, ".webp", StringComparison.OrdinalIgnoreCase);
}
- public void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
+ public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
{
// Even if the caller specified 100, don't use it because it takes forever
quality = Math.Min(quality, 99);
@@ -144,9 +144,13 @@ namespace Emby.Drawing.ImageMagick
originalImage.CurrentImage.TrimImage(10);
}
- if (options.CropWhiteSpace || !originalImageSize.HasValue)
+ var originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height);
+ ImageHelper.SaveImageSize(inputPath, dateModified, originalImageSize);
+
+ if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize))
{
- originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height);
+ // Just spit out the original file if all the options are default
+ return inputPath;
}
var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize);
@@ -174,10 +178,8 @@ namespace Emby.Drawing.ImageMagick
{
using (var originalImage = new MagickWand(inputPath))
{
- if (options.CropWhiteSpace || !originalImageSize.HasValue)
- {
- originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height);
- }
+ var originalImageSize = new ImageSize(originalImage.CurrentImage.Width, originalImage.CurrentImage.Height);
+ ImageHelper.SaveImageSize(inputPath, dateModified, originalImageSize);
var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize);
@@ -205,6 +207,8 @@ namespace Emby.Drawing.ImageMagick
}
}
}
+
+ return outputPath;
}
private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options)
diff --git a/Emby.Drawing.Skia/SkiaEncoder.cs b/Emby.Drawing.Skia/SkiaEncoder.cs
index 018de5bc9..d74279952 100644
--- a/Emby.Drawing.Skia/SkiaEncoder.cs
+++ b/Emby.Drawing.Skia/SkiaEncoder.cs
@@ -191,18 +191,18 @@ namespace Emby.Drawing.Skia
}
private string[] TransparentImageTypes = new string[] { ".png", ".gif", ".webp" };
- private SKBitmap Decode(string path)
+ private SKBitmap Decode(string path, bool forceCleanBitmap = false)
{
var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty);
- if (requiresTransparencyHack)
+ if (requiresTransparencyHack || forceCleanBitmap)
{
using (var stream = new SKFileStream(path))
{
var codec = SKCodec.Create(stream);
// create the bitmap
- var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height);
+ var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack);
// decode
codec.GetPixels(bitmap.Info, bitmap.GetPixels());
@@ -210,7 +210,18 @@ namespace Emby.Drawing.Skia
}
}
- return SKBitmap.Decode(path);
+ var resultBitmap = SKBitmap.Decode(path);
+
+ // If we have to resize these they often end up distorted
+ if (resultBitmap.ColorType == SKColorType.Gray8)
+ {
+ using (resultBitmap)
+ {
+ return Decode(path, true);
+ }
+ }
+
+ return resultBitmap;
}
private SKBitmap GetBitmap(string path, bool cropWhitespace)
@@ -226,7 +237,7 @@ namespace Emby.Drawing.Skia
return Decode(path);
}
- public void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
+ public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
{
if (string.IsNullOrWhiteSpace(inputPath))
{
@@ -246,9 +257,20 @@ namespace Emby.Drawing.Skia
using (var bitmap = GetBitmap(inputPath, options.CropWhiteSpace))
{
- if (options.CropWhiteSpace || !originalImageSize.HasValue)
+ if (bitmap == null)
+ {
+ throw new Exception(string.Format("Skia unable to read image {0}", inputPath));
+ }
+
+ //_logger.Info("Color type {0}", bitmap.Info.ColorType);
+
+ var originalImageSize = new ImageSize(bitmap.Width, bitmap.Height);
+ ImageHelper.SaveImageSize(inputPath, dateModified, originalImageSize);
+
+ if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize))
{
- originalImageSize = new ImageSize(bitmap.Width, bitmap.Height);
+ // Just spit out the original file if all the options are default
+ return inputPath;
}
var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize);
@@ -269,7 +291,7 @@ namespace Emby.Drawing.Skia
using (var outputStream = new SKFileWStream(outputPath))
{
resizedBitmap.Encode(outputStream, skiaOutputFormat, quality);
- return;
+ return outputPath;
}
}
@@ -326,6 +348,7 @@ namespace Emby.Drawing.Skia
}
}
}
+ return outputPath;
}
public void CreateImageCollage(ImageCollageOptions options)
diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs
index 3fa6f6450..89bc96be5 100644
--- a/Emby.Drawing/ImageProcessor.cs
+++ b/Emby.Drawing/ImageProcessor.cs
@@ -75,6 +75,7 @@ namespace Emby.Drawing
ImageEnhancers = new List<IImageEnhancer>();
_saveImageSizeTimer = timerFactory.Create(SaveImageSizeCallback, null, Timeout.Infinite, Timeout.Infinite);
+ ImageHelper.ImageProcessor = this;
Dictionary<Guid, ImageSize> sizeDictionary;
@@ -212,19 +213,12 @@ namespace Emby.Drawing
return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
}
- ImageSize? originalImageSize = null;
- try
- {
- originalImageSize = GetImageSize(originalImagePath, dateModified, true);
- if (options.HasDefaultOptions(originalImagePath, originalImageSize.Value))
- {
- // Just spit out the original file if all the options are default
- return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
- }
- }
- catch
+ ImageSize? originalImageSize = GetSavedImageSize(originalImagePath, dateModified);
+ if (originalImageSize.HasValue && options.HasDefaultOptions(originalImagePath, originalImageSize.Value))
{
- originalImageSize = null;
+ // Just spit out the original file if all the options are default
+ _logger.Info("Returning original image {0}", originalImagePath);
+ return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
}
var newSize = ImageHelper.GetNewImageSize(options, originalImageSize);
@@ -243,7 +237,13 @@ namespace Emby.Drawing
var tmpPath = Path.ChangeExtension(Path.Combine(_appPaths.TempDirectory, Guid.NewGuid().ToString("N")), Path.GetExtension(cacheFilePath));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(tmpPath));
- _imageEncoder.EncodeImage(originalImagePath, originalImageSize, tmpPath, AutoOrient(options.Item), quality, options, outputFormat);
+ var resultPath =_imageEncoder.EncodeImage(originalImagePath, dateModified, tmpPath, AutoOrient(options.Item), quality, options, outputFormat);
+
+ if (string.Equals(resultPath, originalImagePath, StringComparison.OrdinalIgnoreCase))
+ {
+ return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified);
+ }
+
CopyFile(tmpPath, cacheFilePath);
return new Tuple<string, string, DateTime>(tmpPath, GetMimeType(outputFormat, cacheFilePath), _fileSystem.GetLastWriteTimeUtc(tmpPath));
@@ -422,24 +422,70 @@ namespace Emby.Drawing
throw new ArgumentNullException("path");
}
- var name = path + "datemodified=" + imageDateModified.Ticks;
-
ImageSize size;
- var cacheHash = name.GetMD5();
+ var cacheHash = GetImageSizeKey(path, imageDateModified);
if (!_cachedImagedSizes.TryGetValue(cacheHash, out size))
{
size = GetImageSizeInternal(path, allowSlowMethod);
- if (size.Width > 0 && size.Height > 0)
+ SaveImageSize(size, cacheHash, false);
+ }
+
+ return size;
+ }
+
+ public void SaveImageSize(string path, DateTime imageDateModified, ImageSize size)
+ {
+ var cacheHash = GetImageSizeKey(path, imageDateModified);
+ SaveImageSize(size, cacheHash, true);
+ }
+
+ private void SaveImageSize(ImageSize size, Guid cacheHash, bool checkExists)
+ {
+ if (size.Width <= 0 || size.Height <= 0)
+ {
+ return;
+ }
+
+ if (checkExists && _cachedImagedSizes.ContainsKey(cacheHash))
+ {
+ return;
+ }
+
+ if (checkExists)
+ {
+ if (_cachedImagedSizes.TryAdd(cacheHash, size))
{
StartSaveImageSizeTimer();
- _cachedImagedSizes.AddOrUpdate(cacheHash, size, (keyName, oldValue) => size);
}
}
+ else
+ {
+ StartSaveImageSizeTimer();
+ _cachedImagedSizes.AddOrUpdate(cacheHash, size, (keyName, oldValue) => size);
+ }
+ }
- return size;
+ private Guid GetImageSizeKey(string path, DateTime imageDateModified)
+ {
+ var name = path + "datemodified=" + imageDateModified.Ticks;
+ return name.GetMD5();
+ }
+
+ public ImageSize? GetSavedImageSize(string path, DateTime imageDateModified)
+ {
+ ImageSize size;
+
+ var cacheHash = GetImageSizeKey(path, imageDateModified);
+
+ if (_cachedImagedSizes.TryGetValue(cacheHash, out size))
+ {
+ return size;
+ }
+
+ return null;
}
/// <summary>
diff --git a/Emby.Drawing/NullImageEncoder.cs b/Emby.Drawing/NullImageEncoder.cs
index 1723e0637..2241c5a86 100644
--- a/Emby.Drawing/NullImageEncoder.cs
+++ b/Emby.Drawing/NullImageEncoder.cs
@@ -32,7 +32,7 @@ namespace Emby.Drawing
throw new NotImplementedException();
}
- public void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
+ public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
{
throw new NotImplementedException();
}
diff --git a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
index a36cb124d..da6759b34 100644
--- a/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
+++ b/Emby.Server.Implementations/LiveTv/Listings/SchedulesDirect.cs
@@ -167,10 +167,12 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
var programEntry = programDict[schedule.programID];
- var data = images[imageIndex].data ?? new List<ScheduleDirect.ImageData>();
- data = data.OrderByDescending(GetSizeOrder).ToList();
+ var allImages = (images[imageIndex].data ?? new List<ScheduleDirect.ImageData>()).OrderByDescending(GetSizeOrder).ToList();
+ var imagesWithText = allImages.Where(i => string.Equals(i.text, "yes", StringComparison.OrdinalIgnoreCase)).ToList();
+
+ programEntry.primaryImage = GetProgramImage(ApiUrl, imagesWithText, "Logo", true, 600) ??
+ GetProgramImage(ApiUrl, allImages, "Logo", true, 600);
- programEntry.primaryImage = GetProgramImage(ApiUrl, data, "Logo", true, 600);
//programEntry.thumbImage = GetProgramImage(ApiUrl, data, "Iconic", false);
//programEntry.bannerImage = GetProgramImage(ApiUrl, data, "Banner", false) ??
// GetProgramImage(ApiUrl, data, "Banner-L1", false) ??
diff --git a/MediaBrowser.Controller/Drawing/IImageEncoder.cs b/MediaBrowser.Controller/Drawing/IImageEncoder.cs
index 64d997dba..9b895587f 100644
--- a/MediaBrowser.Controller/Drawing/IImageEncoder.cs
+++ b/MediaBrowser.Controller/Drawing/IImageEncoder.cs
@@ -19,7 +19,7 @@ namespace MediaBrowser.Controller.Drawing
/// <summary>
/// Encodes the image.
/// </summary>
- void EncodeImage(string inputPath, ImageSize? originalImageSize, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat outputFormat);
+ string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, int quality, ImageProcessingOptions options, ImageFormat outputFormat);
/// <summary>
/// Creates the image collage.
diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
index a107c1232..7d84719ab 100644
--- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs
+++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
@@ -114,5 +114,7 @@ namespace MediaBrowser.Controller.Drawing
bool SupportsImageCollageCreation { get; }
IImageEncoder ImageEncoder { get; set; }
+
+ void SaveImageSize(string path, DateTime imageDateModified, ImageSize size);
}
}
diff --git a/MediaBrowser.Controller/Drawing/ImageHelper.cs b/MediaBrowser.Controller/Drawing/ImageHelper.cs
index 30c4e90fb..54f2ff987 100644
--- a/MediaBrowser.Controller/Drawing/ImageHelper.cs
+++ b/MediaBrowser.Controller/Drawing/ImageHelper.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Controller.Entities;
+using System;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
@@ -18,6 +19,13 @@ namespace MediaBrowser.Controller.Drawing
return GetSizeEstimate(options);
}
+ public static IImageProcessor ImageProcessor { get; set; }
+
+ public static void SaveImageSize(string path, DateTime dateModified, ImageSize size)
+ {
+ ImageProcessor.SaveImageSize(path, dateModified, size);
+ }
+
private static ImageSize GetSizeEstimate(ImageProcessingOptions options)
{
if (options.Width.HasValue && options.Height.HasValue)
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 29d37f99b..67ba633b7 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -968,7 +968,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
if (bitrate.HasValue && videoStream.BitRate.HasValue)
{
- bitrate = Math.Min(bitrate.Value, videoStream.BitRate.Value);
+ bitrate = GetMinBitrate(bitrate.Value, videoStream.BitRate.Value);
}
}
}
@@ -981,13 +981,25 @@ namespace MediaBrowser.Controller.MediaEncoding
// If a max bitrate was requested, don't let the scaled bitrate exceed it
if (request.VideoBitRate.HasValue)
{
- bitrate = Math.Min(bitrate.Value, request.VideoBitRate.Value);
+ bitrate = GetMinBitrate(bitrate.Value, request.VideoBitRate.Value);
}
}
return bitrate;
}
+ private int GetMinBitrate(int sourceBitrate, int requestedBitrate)
+ {
+ if (sourceBitrate <= 2000000)
+ {
+ sourceBitrate *= 2;
+ }
+
+ var bitrate = Math.Min(sourceBitrate, requestedBitrate);
+
+ return bitrate;
+ }
+
public int? GetAudioBitrateParam(BaseEncodingJobOptions request, MediaStream audioStream)
{
if (request.AudioBitRate.HasValue)