aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api/Images/ImageService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Api/Images/ImageService.cs')
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs187
1 files changed, 126 insertions, 61 deletions
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 2aa680061..f2586b043 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -18,14 +18,14 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
namespace MediaBrowser.Api.Images
{
/// <summary>
/// Class GetItemImage
/// </summary>
- [Route("/Items/{Id}/Images", "GET")]
- [Api(Description = "Gets information about an item's images")]
+ [Route("/Items/{Id}/Images", "GET", Summary = "Gets information about an item's images")]
[Authenticated]
public class GetItemImageInfos : IReturn<List<ImageInfo>>
{
@@ -39,9 +39,10 @@ namespace MediaBrowser.Api.Images
[Route("/Items/{Id}/Images/{Type}", "GET")]
[Route("/Items/{Id}/Images/{Type}/{Index}", "GET")]
+ [Route("/Items/{Id}/Images/{Type}", "HEAD")]
+ [Route("/Items/{Id}/Images/{Type}/{Index}", "HEAD")]
[Route("/Items/{Id}/Images/{Type}/{Index}/{Tag}/{Format}/{MaxWidth}/{MaxHeight}/{PercentPlayed}", "GET")]
[Route("/Items/{Id}/Images/{Type}/{Index}/{Tag}/{Format}/{MaxWidth}/{MaxHeight}/{PercentPlayed}", "HEAD")]
- [Api(Description = "Gets an item image")]
public class GetItemImage : ImageRequest
{
/// <summary>
@@ -55,8 +56,7 @@ namespace MediaBrowser.Api.Images
/// <summary>
/// Class UpdateItemImageIndex
/// </summary>
- [Route("/Items/{Id}/Images/{Type}/{Index}/Index", "POST")]
- [Api(Description = "Updates the index for an item image")]
+ [Route("/Items/{Id}/Images/{Type}/{Index}/Index", "POST", Summary = "Updates the index for an item image")]
[Authenticated]
public class UpdateItemImageIndex : IReturnVoid
{
@@ -106,7 +106,20 @@ namespace MediaBrowser.Api.Images
[Route("/Studios/{Name}/Images/{Type}/{Index}", "GET")]
[Route("/Years/{Year}/Images/{Type}", "GET")]
[Route("/Years/{Year}/Images/{Type}/{Index}", "GET")]
- [Api(Description = "Gets an item by name image")]
+ [Route("/Artists/{Name}/Images/{Type}", "HEAD")]
+ [Route("/Artists/{Name}/Images/{Type}/{Index}", "HEAD")]
+ [Route("/Genres/{Name}/Images/{Type}", "HEAD")]
+ [Route("/Genres/{Name}/Images/{Type}/{Index}", "HEAD")]
+ [Route("/GameGenres/{Name}/Images/{Type}", "HEAD")]
+ [Route("/GameGenres/{Name}/Images/{Type}/{Index}", "HEAD")]
+ [Route("/MusicGenres/{Name}/Images/{Type}", "HEAD")]
+ [Route("/MusicGenres/{Name}/Images/{Type}/{Index}", "HEAD")]
+ [Route("/Persons/{Name}/Images/{Type}", "HEAD")]
+ [Route("/Persons/{Name}/Images/{Type}/{Index}", "HEAD")]
+ [Route("/Studios/{Name}/Images/{Type}", "HEAD")]
+ [Route("/Studios/{Name}/Images/{Type}/{Index}", "HEAD")]
+ [Route("/Years/{Year}/Images/{Type}", "HEAD")]
+ [Route("/Years/{Year}/Images/{Type}/{Index}", "HEAD")]
public class GetItemByNameImage : ImageRequest
{
/// <summary>
@@ -122,7 +135,8 @@ namespace MediaBrowser.Api.Images
/// </summary>
[Route("/Users/{Id}/Images/{Type}", "GET")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "GET")]
- [Api(Description = "Gets a user image")]
+ [Route("/Users/{Id}/Images/{Type}", "HEAD")]
+ [Route("/Users/{Id}/Images/{Type}/{Index}", "HEAD")]
public class GetUserImage : ImageRequest
{
/// <summary>
@@ -138,7 +152,6 @@ namespace MediaBrowser.Api.Images
/// </summary>
[Route("/Items/{Id}/Images/{Type}", "DELETE")]
[Route("/Items/{Id}/Images/{Type}/{Index}", "DELETE")]
- [Api(Description = "Deletes an item image")]
[Authenticated]
public class DeleteItemImage : DeleteImageRequest, IReturnVoid
{
@@ -155,7 +168,6 @@ namespace MediaBrowser.Api.Images
/// </summary>
[Route("/Users/{Id}/Images/{Type}", "DELETE")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "DELETE")]
- [Api(Description = "Deletes a user image")]
[Authenticated]
public class DeleteUserImage : DeleteImageRequest, IReturnVoid
{
@@ -172,7 +184,6 @@ namespace MediaBrowser.Api.Images
/// </summary>
[Route("/Users/{Id}/Images/{Type}", "POST")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "POST")]
- [Api(Description = "Posts a user image")]
[Authenticated]
public class PostUserImage : DeleteImageRequest, IRequiresRequestStream, IReturnVoid
{
@@ -294,36 +305,6 @@ namespace MediaBrowser.Api.Images
}
}
- var video = item as Video;
-
- if (video != null)
- {
- var index = 0;
-
- foreach (var chapter in _itemRepo.GetChapters(video.Id))
- {
- if (!string.IsNullOrEmpty(chapter.ImagePath))
- {
- var image = chapter.ImagePath;
-
- var info = GetImageInfo(item, new ItemImageInfo
- {
- Path = image,
- Type = ImageType.Chapter,
- DateModified = _fileSystem.GetLastWriteTimeUtc(image)
-
- }, index);
-
- if (info != null)
- {
- list.Add(info);
- }
- }
-
- index++;
- }
- }
-
return list;
}
@@ -333,8 +314,20 @@ namespace MediaBrowser.Api.Images
{
var fileInfo = new FileInfo(info.Path);
- var size = _imageProcessor.GetImageSize(info.Path);
+ int? width = null;
+ int? height = null;
+
+ try
+ {
+ var size = _imageProcessor.GetImageSize(info.Path, info.DateModified);
+
+ width = Convert.ToInt32(size.Width);
+ height = Convert.ToInt32(size.Height);
+ }
+ catch
+ {
+ }
return new ImageInfo
{
Path = info.Path,
@@ -342,8 +335,8 @@ namespace MediaBrowser.Api.Images
ImageType = info.Type,
ImageTag = _imageProcessor.GetImageCacheTag(item, info),
Size = fileInfo.Length,
- Width = Convert.ToInt32(size.Width),
- Height = Convert.ToInt32(size.Height)
+ Width = width,
+ Height = height
};
}
catch (Exception ex)
@@ -389,11 +382,18 @@ namespace MediaBrowser.Api.Images
/// <returns>System.Object.</returns>
public object Get(GetUserImage request)
{
- var item = _userManager.Users.First(i => i.Id == request.Id);
+ var item = _userManager.GetUserById(request.Id);
return GetImage(request, item, false);
}
+ public object Head(GetUserImage request)
+ {
+ var item = _userManager.GetUserById(request.Id);
+
+ return GetImage(request, item, true);
+ }
+
public object Get(GetItemByNameImage request)
{
var pathInfo = PathInfo.Parse(Request.PathInfo);
@@ -404,6 +404,16 @@ namespace MediaBrowser.Api.Images
return GetImage(request, item, false);
}
+ public object Head(GetItemByNameImage request)
+ {
+ var pathInfo = PathInfo.Parse(Request.PathInfo);
+ var type = pathInfo.GetArgumentValue<string>(0);
+
+ var item = GetItemByName(request.Name, type, _libraryManager);
+
+ return GetImage(request, item, true);
+ }
+
/// <summary>
/// Posts the specified request.
/// </summary>
@@ -415,7 +425,7 @@ namespace MediaBrowser.Api.Images
request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue<string>(3), true);
- var item = _userManager.Users.First(i => i.Id == id);
+ var item = _userManager.GetUserById(id);
var task = PostImage(item, request.RequestStream, request.Type, Request.ContentType);
@@ -446,7 +456,7 @@ namespace MediaBrowser.Api.Images
/// <param name="request">The request.</param>
public void Delete(DeleteUserImage request)
{
- var item = _userManager.Users.First(i => i.Id == request.Id);
+ var item = _userManager.GetUserById(request.Id);
var task = item.DeleteImage(request.Type, request.Index ?? 0);
@@ -525,7 +535,8 @@ namespace MediaBrowser.Api.Images
}).ToList() : new List<IImageEnhancer>();
- var contentType = GetMimeType(request.Format, imageInfo.Path);
+ var format = GetOutputFormat(request, imageInfo, supportedImageEnhancers);
+ var contentType = GetMimeType(format, imageInfo.Path);
var cacheGuid = new Guid(_imageProcessor.GetImageCacheTag(item, imageInfo, supportedImageEnhancers));
@@ -545,6 +556,7 @@ namespace MediaBrowser.Api.Images
return GetImageResult(item,
request,
imageInfo,
+ format,
supportedImageEnhancers,
contentType,
cacheDuration,
@@ -556,6 +568,7 @@ namespace MediaBrowser.Api.Images
private async Task<object> GetImageResult(IHasImages item,
ImageRequest request,
ItemImageInfo image,
+ ImageFormat format,
List<IImageEnhancer> enhancers,
string contentType,
TimeSpan? cacheDuration,
@@ -581,11 +594,11 @@ namespace MediaBrowser.Api.Images
MaxWidth = request.MaxWidth,
Quality = request.Quality,
Width = request.Width,
- OutputFormat = request.Format,
AddPlayedIndicator = request.AddPlayedIndicator,
PercentPlayed = request.PercentPlayed ?? 0,
UnplayedCount = request.UnplayedCount,
- BackgroundColor = request.BackgroundColor
+ BackgroundColor = request.BackgroundColor,
+ OutputFormat = format
};
var file = await _imageProcessor.ProcessImage(options).ConfigureAwait(false);
@@ -600,30 +613,82 @@ namespace MediaBrowser.Api.Images
});
}
- private string GetMimeType(ImageOutputFormat format, string path)
+ 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;
+ }
+
+ private ImageFormat[] GetClientSupportedFormats()
+ {
+ if ((Request.AcceptTypes ?? new string[] { }).Contains("image/webp", StringComparer.OrdinalIgnoreCase))
+ {
+ var userAgent = Request.UserAgent ?? string.Empty;
+
+ // Not displaying properly on iOS
+ if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ return new[] { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
+ }
+ }
+
+ return new[] { ImageFormat.Jpg, ImageFormat.Png };
+ }
+
+ private string GetMimeType(ImageFormat format, string path)
{
- if (format == ImageOutputFormat.Bmp)
+ if (format == ImageFormat.Bmp)
{
- return Common.Net.MimeTypes.GetMimeType("i.bmp");
+ return MimeTypes.GetMimeType("i.bmp");
}
- if (format == ImageOutputFormat.Gif)
+ if (format == ImageFormat.Gif)
{
- return Common.Net.MimeTypes.GetMimeType("i.gif");
+ return MimeTypes.GetMimeType("i.gif");
}
- if (format == ImageOutputFormat.Jpg)
+ if (format == ImageFormat.Jpg)
{
- return Common.Net.MimeTypes.GetMimeType("i.jpg");
+ return MimeTypes.GetMimeType("i.jpg");
}
- if (format == ImageOutputFormat.Png)
+ if (format == ImageFormat.Png)
{
- return Common.Net.MimeTypes.GetMimeType("i.png");
+ return MimeTypes.GetMimeType("i.png");
}
- if (format == ImageOutputFormat.Webp)
+ if (format == ImageFormat.Webp)
{
- return Common.Net.MimeTypes.GetMimeType("i.webp");
+ return MimeTypes.GetMimeType("i.webp");
}
- return Common.Net.MimeTypes.GetMimeType(path);
+ return MimeTypes.GetMimeType(path);
}
/// <summary>