DynamicImageHelpers.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using ImageMagickSharp;
  2. using MediaBrowser.Common.Configuration;
  3. using MediaBrowser.Common.IO;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Threading.Tasks;
  9. namespace MediaBrowser.Server.Implementations.Photos
  10. {
  11. public static class DynamicImageHelpers
  12. {
  13. public static async Task<Stream> GetThumbCollage(List<string> files,
  14. IFileSystem fileSystem,
  15. int width,
  16. int height, IApplicationPaths appPaths)
  17. {
  18. if (files.Any(string.IsNullOrWhiteSpace))
  19. {
  20. throw new ArgumentException("Empty file found in files list");
  21. }
  22. if (files.Count < 3)
  23. {
  24. return await GetSingleImage(files, fileSystem).ConfigureAwait(false);
  25. }
  26. const int rows = 1;
  27. const int cols = 3;
  28. int cellWidth = 2 * (width / 3);
  29. int cellHeight = height;
  30. var index = 0;
  31. using (var wand = new MagickWand(width, height, new PixelWand(ColorName.None, 1)))
  32. {
  33. for (var row = 0; row < rows; row++)
  34. {
  35. for (var col = 0; col < cols; col++)
  36. {
  37. var x = col * (cellWidth / 2);
  38. var y = row * cellHeight;
  39. if (files.Count > index)
  40. {
  41. using (var innerWand = new MagickWand(files[index]))
  42. {
  43. innerWand.CurrentImage.ResizeImage(cellWidth, cellHeight);
  44. wand.CurrentImage.CompositeImage(innerWand, CompositeOperator.OverCompositeOp, x, y);
  45. }
  46. }
  47. index++;
  48. }
  49. }
  50. return GetStream(wand, appPaths);
  51. }
  52. }
  53. public static async Task<Stream> GetSquareCollage(List<string> files,
  54. IFileSystem fileSystem,
  55. int size, IApplicationPaths appPaths)
  56. {
  57. if (files.Any(string.IsNullOrWhiteSpace))
  58. {
  59. throw new ArgumentException("Empty file found in files list");
  60. }
  61. if (files.Count < 4)
  62. {
  63. return await GetSingleImage(files, fileSystem).ConfigureAwait(false);
  64. }
  65. const int rows = 2;
  66. const int cols = 2;
  67. int singleSize = size / 2;
  68. var index = 0;
  69. using (var wand = new MagickWand(size, size, new PixelWand(ColorName.None, 1)))
  70. {
  71. for (var row = 0; row < rows; row++)
  72. {
  73. for (var col = 0; col < cols; col++)
  74. {
  75. var x = col * singleSize;
  76. var y = row * singleSize;
  77. using (var innerWand = new MagickWand(files[index]))
  78. {
  79. innerWand.CurrentImage.ResizeImage(singleSize, singleSize);
  80. wand.CurrentImage.CompositeImage(innerWand, CompositeOperator.OverCompositeOp, x, y);
  81. }
  82. index++;
  83. }
  84. }
  85. return GetStream(wand, appPaths);
  86. }
  87. }
  88. private static Task<Stream> GetSingleImage(List<string> files, IFileSystem fileSystem)
  89. {
  90. return Task.FromResult<Stream>(fileSystem.GetFileStream(files[0], FileMode.Open, FileAccess.Read, FileShare.Read));
  91. }
  92. private static Stream GetStream(MagickWand image, IApplicationPaths appPaths)
  93. {
  94. var tempFile = Path.Combine(appPaths.TempDirectory, Guid.NewGuid().ToString("N") + ".png");
  95. Directory.CreateDirectory(Path.GetDirectoryName(tempFile));
  96. image.CurrentImage.CompressionQuality = 100;
  97. image.SaveImage(tempFile);
  98. return File.OpenRead(tempFile);
  99. }
  100. }
  101. }