Merge pull request #1859 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-06-18 13:29:46 -04:00 committed by GitHub
commit f35a5e553f
8 changed files with 52 additions and 463 deletions

View File

@ -80,7 +80,6 @@
<Compile Include="ImageMagick\UnplayedCountIndicator.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="ImageMagick\fonts\MontserratLight.otf" />
<EmbeddedResource Include="ImageMagick\fonts\robotoregular.ttf" />
</ItemGroup>
<ItemGroup>

View File

@ -284,15 +284,15 @@ namespace Emby.Drawing.ImageMagick
if (ratio >= 1.4)
{
new StripCollageBuilder(_appPaths, _fileSystem).BuildThumbCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height, options.Text);
new StripCollageBuilder(_appPaths, _fileSystem).BuildThumbCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
}
else if (ratio >= .9)
{
new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height, options.Text);
new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
}
else
{
new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height, options.Text);
new StripCollageBuilder(_appPaths, _fileSystem).BuildPosterCollage(options.InputPaths.ToList(), options.OutputPath, options.Width, options.Height);
}
SaveDelay();

View File

@ -9,140 +9,35 @@ namespace Emby.Drawing.ImageMagick
public class StripCollageBuilder
{
private readonly IApplicationPaths _appPaths;
private readonly IFileSystem _fileSystem;
private readonly IFileSystem _fileSystem;
public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem)
public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem)
{
_appPaths = appPaths;
_fileSystem = fileSystem;
_fileSystem = fileSystem;
}
public void BuildPosterCollage(List<string> paths, string outputPath, int width, int height, string text)
public void BuildPosterCollage(List<string> paths, string outputPath, int width, int height)
{
if (!string.IsNullOrWhiteSpace(text))
using (var wand = BuildPosterCollageWand(paths, width, height))
{
using (var wand = BuildPosterCollageWandWithText(paths, text, width, height))
{
wand.SaveImage(outputPath);
}
}
else
{
using (var wand = BuildPosterCollageWand(paths, width, height))
{
wand.SaveImage(outputPath);
}
wand.SaveImage(outputPath);
}
}
public void BuildSquareCollage(List<string> paths, string outputPath, int width, int height, string text)
public void BuildSquareCollage(List<string> paths, string outputPath, int width, int height)
{
if (!string.IsNullOrWhiteSpace(text))
using (var wand = BuildSquareCollageWand(paths, width, height))
{
using (var wand = BuildSquareCollageWandWithText(paths, text, width, height))
{
wand.SaveImage(outputPath);
}
}
else
{
using (var wand = BuildSquareCollageWand(paths, width, height))
{
wand.SaveImage(outputPath);
}
wand.SaveImage(outputPath);
}
}
public void BuildThumbCollage(List<string> paths, string outputPath, int width, int height, string text)
public void BuildThumbCollage(List<string> paths, string outputPath, int width, int height)
{
if (!string.IsNullOrWhiteSpace(text))
using (var wand = BuildThumbCollageWand(paths, width, height))
{
using (var wand = BuildThumbCollageWandWithText(paths, text, width, height))
{
wand.SaveImage(outputPath);
}
}
else
{
using (var wand = BuildThumbCollageWand(paths, width, height))
{
wand.SaveImage(outputPath);
}
}
}
private MagickWand BuildThumbCollageWandWithText(List<string> paths, string text, int width, int height)
{
var inputPaths = ImageHelpers.ProjectPaths(paths, 8);
using (var wandImages = new MagickWand(inputPaths.ToArray()))
{
var wand = new MagickWand(width, height);
wand.OpenImage("gradient:#111111-#111111");
using (var draw = new DrawingWand())
{
using (var fcolor = new PixelWand(ColorName.White))
{
draw.FillColor = fcolor;
draw.Font = MontserratLightFont;
draw.FontSize = 60;
draw.FontWeight = FontWeightType.LightStyle;
draw.TextAntialias = true;
}
var fontMetrics = wand.QueryFontMetrics(draw, text);
var textContainerY = Convert.ToInt32(height * .165);
wand.CurrentImage.AnnotateImage(draw, (width - fontMetrics.TextWidth) / 2, textContainerY, 0.0, text);
var iSlice = Convert.ToInt32(width * .1166666667);
int iTrans = Convert.ToInt32(height * 0.2);
int iHeight = Convert.ToInt32(height * 0.46296296296296296296296296296296);
var horizontalImagePadding = Convert.ToInt32(width * 0.0125);
foreach (var element in wandImages.ImageList)
{
int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
element.Gravity = GravityType.CenterGravity;
element.BackgroundColor = new PixelWand("none", 1);
element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
int ix = (int)Math.Abs((iWidth - iSlice) / 2);
element.CropImage(iSlice, iHeight, ix, 0);
element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
}
wandImages.SetFirstIterator();
using (var wandList = wandImages.AppendImages())
{
wandList.CurrentImage.TrimImage(1);
using (var mwr = wandList.CloneMagickWand())
{
using (var blackPixelWand = new PixelWand(ColorName.Black))
{
using (var greyPixelWand = new PixelWand(ColorName.Grey70))
{
mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
mwr.CurrentImage.FlipImage();
mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
{
mwg.OpenImage("gradient:black-none");
var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.DstInCompositeOp, 0, verticalSpacing);
wandList.AddImage(mwr);
int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * 0.26851851851851851851851851851852));
}
}
}
}
}
}
return wand;
wand.SaveImage(outputPath);
}
}
@ -211,81 +106,6 @@ namespace Emby.Drawing.ImageMagick
}
}
private MagickWand BuildPosterCollageWandWithText(List<string> paths, string label, int width, int height)
{
var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
using (var wandImages = new MagickWand(inputPaths.ToArray()))
{
var wand = new MagickWand(width, height);
wand.OpenImage("gradient:#111111-#111111");
using (var draw = new DrawingWand())
{
using (var fcolor = new PixelWand(ColorName.White))
{
draw.FillColor = fcolor;
draw.Font = MontserratLightFont;
draw.FontSize = 60;
draw.FontWeight = FontWeightType.LightStyle;
draw.TextAntialias = true;
}
var fontMetrics = wand.QueryFontMetrics(draw, label);
var textContainerY = Convert.ToInt32(height * .165);
wand.CurrentImage.AnnotateImage(draw, (width - fontMetrics.TextWidth) / 2, textContainerY, 0.0, label);
var iSlice = Convert.ToInt32(width * 0.225);
int iTrans = Convert.ToInt32(height * 0.2);
int iHeight = Convert.ToInt32(height * 0.46296296296296296296296296296296);
var horizontalImagePadding = Convert.ToInt32(width * 0.0275);
foreach (var element in wandImages.ImageList)
{
int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
element.Gravity = GravityType.CenterGravity;
element.BackgroundColor = new PixelWand("none", 1);
element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
int ix = (int)Math.Abs((iWidth - iSlice) / 2);
element.CropImage(iSlice, iHeight, ix, 0);
element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
}
wandImages.SetFirstIterator();
using (var wandList = wandImages.AppendImages())
{
wandList.CurrentImage.TrimImage(1);
using (var mwr = wandList.CloneMagickWand())
{
using (var blackPixelWand = new PixelWand(ColorName.Black))
{
using (var greyPixelWand = new PixelWand(ColorName.Grey70))
{
mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
mwr.CurrentImage.FlipImage();
mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
{
mwg.OpenImage("gradient:black-none");
var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.DstInCompositeOp, 0, verticalSpacing);
wandList.AddImage(mwr);
int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * 0.26851851851851851851851851851852));
}
}
}
}
}
}
return wand;
}
}
private MagickWand BuildThumbCollageWand(List<string> paths, int width, int height)
{
var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
@ -352,148 +172,29 @@ namespace Emby.Drawing.ImageMagick
}
private MagickWand BuildSquareCollageWand(List<string> paths, int width, int height)
{
var inputPaths = ImageHelpers.ProjectPaths(paths, 3);
using (var wandImages = new MagickWand(inputPaths.ToArray()))
{
var wand = new MagickWand(width, height);
wand.OpenImage("gradient:#111111-#111111");
using (var draw = new DrawingWand())
{
var iSlice = Convert.ToInt32(width * .32);
int iTrans = Convert.ToInt32(height * .25);
int iHeight = Convert.ToInt32(height * .68);
var horizontalImagePadding = Convert.ToInt32(width * 0.02);
foreach (var element in wandImages.ImageList)
{
using (var blackPixelWand = new PixelWand(ColorName.Black))
{
int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
element.Gravity = GravityType.CenterGravity;
element.BackgroundColor = blackPixelWand;
element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
int ix = (int)Math.Abs((iWidth - iSlice) / 2);
element.CropImage(iSlice, iHeight, ix, 0);
element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
}
}
wandImages.SetFirstIterator();
using (var wandList = wandImages.AppendImages())
{
wandList.CurrentImage.TrimImage(1);
using (var mwr = wandList.CloneMagickWand())
{
using (var blackPixelWand = new PixelWand(ColorName.Black))
{
using (var greyPixelWand = new PixelWand(ColorName.Grey70))
{
mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
mwr.CurrentImage.FlipImage();
mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
{
mwg.OpenImage("gradient:black-none");
var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.CopyOpacityCompositeOp, 0, verticalSpacing);
wandList.AddImage(mwr);
int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .03));
}
}
}
}
}
}
return wand;
}
}
private MagickWand BuildSquareCollageWandWithText(List<string> paths, string label, int width, int height)
{
var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
using (var wandImages = new MagickWand(inputPaths.ToArray()))
var outputWand = new MagickWand(width, height, new PixelWand("none", 1));
var imageIndex = 0;
var cellWidth = width/2;
var cellHeight = height/2;
for (var x = 0; x < 2; x++)
{
var wand = new MagickWand(width, height);
wand.OpenImage("gradient:#111111-#111111");
using (var draw = new DrawingWand())
for (var y = 0; y < 2; y++)
{
using (var fcolor = new PixelWand(ColorName.White))
using (var temp = new MagickWand(inputPaths[imageIndex]))
{
draw.FillColor = fcolor;
draw.Font = MontserratLightFont;
draw.FontSize = 60;
draw.FontWeight = FontWeightType.LightStyle;
draw.TextAntialias = true;
}
var fontMetrics = wand.QueryFontMetrics(draw, label);
var textContainerY = Convert.ToInt32(height * .165);
wand.CurrentImage.AnnotateImage(draw, (width - fontMetrics.TextWidth) / 2, textContainerY, 0.0, label);
var iSlice = Convert.ToInt32(width * .225);
int iTrans = Convert.ToInt32(height * 0.2);
int iHeight = Convert.ToInt32(height * 0.46296296296296296296296296296296);
var horizontalImagePadding = Convert.ToInt32(width * 0.02);
foreach (var element in wandImages.ImageList)
{
int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
element.Gravity = GravityType.CenterGravity;
element.BackgroundColor = new PixelWand("none", 1);
element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
int ix = (int)Math.Abs((iWidth - iSlice) / 2);
element.CropImage(iSlice, iHeight, ix, 0);
element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
}
wandImages.SetFirstIterator();
using (var wandList = wandImages.AppendImages())
{
wandList.CurrentImage.TrimImage(1);
using (var mwr = wandList.CloneMagickWand())
{
using (var blackPixelWand = new PixelWand(ColorName.Black))
{
using (var greyPixelWand = new PixelWand(ColorName.Grey70))
{
mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
mwr.CurrentImage.FlipImage();
mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
{
mwg.OpenImage("gradient:black-none");
var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.DstInCompositeOp, 0, verticalSpacing);
wandList.AddImage(mwr);
int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * 0.26851851851851851851851851851852));
}
}
}
}
temp.CurrentImage.ScaleImage(cellWidth, cellHeight);
// draw this image into the strip at the next position
var xPos = x*cellWidth;
var yPos = y*cellHeight;
outputWand.CurrentImage.CompositeImage(temp, CompositeOperator.OverCompositeOp, xPos, yPos);
}
imageIndex++;
}
return wand;
}
}
private string MontserratLightFont
{
get { return PlayedIndicatorDrawer.ExtractFont("MontserratLight.otf", _appPaths, _fileSystem); }
return outputWand;
}
}
}

View File

@ -23,10 +23,5 @@ namespace MediaBrowser.Controller.Drawing
/// </summary>
/// <value>The height.</value>
public int Height { get; set; }
/// <summary>
/// Gets or sets the text.
/// </summary>
/// <value>The text.</value>
public string Text { get; set; }
}
}

View File

@ -75,15 +75,12 @@ namespace MediaBrowser.Model.Entities
{
attributes.Add(StringHelper.ToStringCultureInvariant(Channels.Value) + " ch");
}
string name = string.Join(" ", attributes.ToArray());
if (IsDefault)
{
name += " (D)";
attributes.Add("Default");
}
return name;
return string.Join(" ", attributes.ToArray());
}
if (Type == MediaStreamType.Subtitle)
@ -94,27 +91,17 @@ namespace MediaBrowser.Model.Entities
{
attributes.Add(StringHelper.FirstToUpper(Language));
}
if (!string.IsNullOrEmpty(Codec))
{
attributes.Add(Codec);
}
string name = string.Join(" ", attributes.ToArray());
if (IsDefault)
{
name += " (D)";
attributes.Add("Default");
}
if (IsForced)
{
name += " (F)";
attributes.Add("Forced");
}
if (IsExternal)
{
name += " (EXT)";
}
string name = string.Join(" ", attributes.ToArray());
return name;
}

View File

@ -471,30 +471,16 @@ namespace MediaBrowser.Server.Implementations.Dto
{
var folder = (Folder)item;
if (fields.Contains(ItemFields.SyncInfo))
// Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice
// TODO: Improve in future
dto.UserData = GetUserItemDataDto(_userDataRepository.GetUserData(user, item));
if (item.SourceType == SourceType.Library && folder.SupportsUserDataFromChildren)
{
var userData = _userDataRepository.GetUserData(user, item);
// Skip the user data manager because we've already looped through the recursive tree and don't want to do it twice
// TODO: Improve in future
dto.UserData = GetUserItemDataDto(userData);
if (item.SourceType == SourceType.Library && folder.SupportsUserDataFromChildren)
{
SetSpecialCounts(folder, user, dto, fields, syncProgress);
}
SetSpecialCounts(folder, user, dto, fields, syncProgress);
dto.UserData.Played = dto.UserData.PlayedPercentage.HasValue && dto.UserData.PlayedPercentage.Value >= 100;
}
else if (item.SourceType == SourceType.Library)
{
dto.UserData = _userDataRepository.GetUserDataDto(item, user);
}
else
{
var userData = _userDataRepository.GetUserData(user, item);
dto.UserData = GetUserItemDataDto(userData);
}
if (item.SourceType == SourceType.Library)
{
@ -549,6 +535,13 @@ namespace MediaBrowser.Server.Implementations.Dto
private int GetChildCount(Folder folder, User user)
{
// Right now this is too slow to calculate for top level folders on a per-user basis
// Just return something so that apps that are expecting a value won't think the folders are empty
if (folder is ICollectionFolder || folder is UserView)
{
return new Random().Next(1, 10);
}
return folder.GetChildCount(user);
}

View File

@ -1735,6 +1735,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
var now = DateTime.UtcNow;
var list = new List<BaseItem>();
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + GetFromText();
@ -1778,11 +1780,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
var item = GetItem(reader);
if (item != null)
{
yield return item;
list.Add(item);
}
}
}
}
return list;
}
private void LogQueryTime(string methodName, IDbCommand cmd, DateTime startDate)

View File

@ -259,9 +259,6 @@ namespace MediaBrowser.ServerApplication
task = InstallVcredist2013IfNeeded(_appHost, _logger);
Task.WaitAll(task);
task = InstallFrameworkV46IfNeeded(_logger);
Task.WaitAll(task);
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
@ -594,93 +591,6 @@ namespace MediaBrowser.ServerApplication
}
}
private static async Task InstallFrameworkV46IfNeeded(ILogger logger)
{
bool installFrameworkV46 = false;
try
{
using (RegistryKey ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
.OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\"))
{
if (ndpKey != null && ndpKey.GetValue("Release") != null)
{
if ((int)ndpKey.GetValue("Release") <= 393295)
{
//Found framework V4, but not yet V4.6
installFrameworkV46 = true;
}
}
else
{
//Nothing found in the registry for V4
installFrameworkV46 = true;
}
}
}
catch (Exception ex)
{
logger.ErrorException("Error getting .NET Framework version", ex);
}
_logger.Info(".NET Framework 4.6 found: {0}", !installFrameworkV46);
if (installFrameworkV46)
{
try
{
await InstallFrameworkV46().ConfigureAwait(false);
}
catch (Exception ex)
{
logger.ErrorException("Error installing .NET Framework version 4.6", ex);
}
}
}
private static async Task InstallFrameworkV46()
{
var httpClient = _appHost.HttpClient;
var tmp = await httpClient.GetTempFile(new HttpRequestOptions
{
Url = "https://github.com/MediaBrowser/Emby.Resources/raw/master/netframeworkV46/NDP46-KB3045560-Web.exe",
Progress = new Progress<double>()
}).ConfigureAwait(false);
var exePath = Path.ChangeExtension(tmp, ".exe");
File.Copy(tmp, exePath);
var startInfo = new ProcessStartInfo
{
FileName = exePath,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
Verb = "runas",
ErrorDialog = false,
Arguments = "/q /norestart"
};
_logger.Info("Running {0}", startInfo.FileName);
using (var process = Process.Start(startInfo))
{
process.WaitForExit();
//process.ExitCode
/*
0 --> Installation completed successfully.
1602 --> The user canceled installation.
1603 --> A fatal error occurred during installation.
1641 --> A restart is required to complete the installation. This message indicates success.
3010 --> A restart is required to complete the installation. This message indicates success.
5100 --> The user's computer does not meet system requirements.
*/
}
}
private static async Task InstallVcredist2013IfNeeded(ApplicationHost appHost, ILogger logger)
{
try