Fixed: ImageResizer Tweaks

Co-Authored-By: taloth <taloth@users.noreply.github.com>
Co-Authored-By: ta264 <ta264@users.noreply.github.com>
This commit is contained in:
Qstick 2019-10-14 21:21:00 +01:00
parent bc0cc2bfa9
commit 225430162b
4 changed files with 58 additions and 19 deletions

View File

@ -4,7 +4,9 @@ using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Core.Test.Framework;
using SixLabors.ImageSharp;
namespace NzbDrone.Core.Test.MediaCoverTests
{
@ -14,13 +16,10 @@ namespace NzbDrone.Core.Test.MediaCoverTests
[SetUp]
public void SetUp()
{
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.OpenReadStream(It.IsAny<string>()))
.Returns<string>(s => new FileStream(s, FileMode.Open));
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.OpenWriteStream(It.IsAny<string>()))
.Returns<string>(s => new FileStream(s, FileMode.Create));
if (PlatformInfo.IsMono && PlatformInfo.GetVersion() < new Version(5, 8))
{
Assert.Inconclusive("Not supported on Mono < 5.8");
}
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FileExists(It.IsAny<string>()))
@ -29,10 +28,8 @@ namespace NzbDrone.Core.Test.MediaCoverTests
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.DeleteFile(It.IsAny<string>()))
.Callback<string>(s => File.Delete(s));
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.CanUseGDIPlus())
.Returns(true);
Mocker.SetConstant<IPlatformInfo>(Mocker.Resolve<PlatformInfo>());
}
[Test]
@ -49,9 +46,11 @@ namespace NzbDrone.Core.Test.MediaCoverTests
fileInfo.Exists.Should().BeTrue();
fileInfo.Length.Should().BeInRange(1000, 30000);
var image = System.Drawing.Image.FromFile(resizedFile);
image.Height.Should().Be(170);
image.Width.Should().Be(170);
using (var image = Image.Load(resizedFile))
{
image.Height.Should().Be(170);
image.Width.Should().Be(170);
}
}
[Test]

View File

@ -1,6 +1,8 @@
using System;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;
using SixLabors.Memory;
@ -14,23 +16,39 @@ namespace NzbDrone.Core.MediaCover
public class ImageResizer : IImageResizer
{
private readonly IDiskProvider _diskProvider;
private readonly bool _enabled;
public ImageResizer(IDiskProvider diskProvider)
public ImageResizer(IDiskProvider diskProvider, IPlatformInfo platformInfo)
{
_diskProvider = diskProvider;
// Random segfaults on mono 5.0 and 5.4
if (PlatformInfo.IsMono && platformInfo.Version < new System.Version(5, 8))
{
return;
}
_enabled = true;
// More conservative memory allocation
SixLabors.ImageSharp.Configuration.Default.MemoryAllocator = new SimpleGcMemoryAllocator();
// Thumbnails don't need super high quality
SixLabors.ImageSharp.Configuration.Default.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder
{
Quality = 92
});
}
public void Resize(string source, string destination, int height)
{
if (!_enabled) return;
try
{
using (var image = Image.Load(source))
{
var width = (int)Math.Floor((double)image.Width * (double)height / (double)image.Height);
image.Mutate(x => x.Resize(width, height));
image.Mutate(x => x.Resize(0, height));
image.Save(destination);
}
}

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
@ -40,6 +41,11 @@ namespace NzbDrone.Core.MediaCover
private readonly string _coverRootFolder;
// ImageSharp is slow on ARM (no hardware acceleration on mono yet)
// So limit the number of concurrent resizing tasks
private static SemaphoreSlim _semaphore = new SemaphoreSlim((int)Math.Ceiling(Environment.ProcessorCount / 2.0));
public MediaCoverService(IImageResizer resizer,
IHttpClient httpClient,
IDiskProvider diskProvider,
@ -94,6 +100,8 @@ namespace NzbDrone.Core.MediaCover
private void EnsureCovers(Movie movie, int retried = 0)
{
var toResize = new List<Tuple<MediaCover, bool>>();
foreach (var cover in movie.Images)
{
var fileName = GetCoverPath(movie.Id, cover.CoverType);
@ -133,7 +141,21 @@ namespace NzbDrone.Core.MediaCover
_logger.Error(e, "Couldn't download media cover for {0}", movie);
}
EnsureResizedCovers(movie, cover, !alreadyExists);
toResize.Add(Tuple.Create(cover, alreadyExists));
}
try
{
_semaphore.Wait();
foreach (var tuple in toResize)
{
EnsureResizedCovers(movie, tuple.Item1, !tuple.Item2);
}
}
finally
{
_semaphore.Release();
}
}

View File

@ -68,7 +68,7 @@ namespace NzbDrone.Test.Common
return;
}
Console.WriteLine("Waiting for Radarr to start. Response Status : {0} [{1}] {2}", statusCall.ResponseStatus, statusCall.StatusDescription, statusCall.ErrorException);
Console.WriteLine("Waiting for Radarr to start. Response Status : {0} [{1}] {2}", statusCall.ResponseStatus, statusCall.StatusDescription, statusCall.ErrorException.Message);
Thread.Sleep(500);
}