StripCollageBuilder.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. using ImageMagickSharp;
  2. using MediaBrowser.Common.Configuration;
  3. using System;
  4. using System.Collections.Generic;
  5. using MediaBrowser.Controller.IO;
  6. using MediaBrowser.Model.IO;
  7. namespace Emby.Drawing.ImageMagick
  8. {
  9. public class StripCollageBuilder
  10. {
  11. private readonly IApplicationPaths _appPaths;
  12. private readonly IFileSystem _fileSystem;
  13. public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem)
  14. {
  15. _appPaths = appPaths;
  16. _fileSystem = fileSystem;
  17. }
  18. public void BuildPosterCollage(string[] paths, string outputPath, int width, int height)
  19. {
  20. using (var wand = BuildPosterCollageWand(paths, width, height))
  21. {
  22. wand.SaveImage(outputPath);
  23. }
  24. }
  25. public void BuildSquareCollage(string[] paths, string outputPath, int width, int height)
  26. {
  27. using (var wand = BuildSquareCollageWand(paths, width, height))
  28. {
  29. wand.SaveImage(outputPath);
  30. }
  31. }
  32. public void BuildThumbCollage(string[] paths, string outputPath, int width, int height)
  33. {
  34. using (var wand = BuildThumbCollageWand(paths, width, height))
  35. {
  36. wand.SaveImage(outputPath);
  37. }
  38. }
  39. private MagickWand BuildPosterCollageWand(string[] paths, int width, int height)
  40. {
  41. var inputPaths = ImageHelpers.ProjectPaths(paths, 3);
  42. using (var wandImages = new MagickWand(inputPaths.ToArray()))
  43. {
  44. var wand = new MagickWand(width, height);
  45. wand.OpenImage("gradient:#111111-#111111");
  46. using (var draw = new DrawingWand())
  47. {
  48. var iSlice = Convert.ToInt32(width * 0.3);
  49. int iTrans = Convert.ToInt32(height * .25);
  50. int iHeight = Convert.ToInt32(height * .65);
  51. var horizontalImagePadding = Convert.ToInt32(width * 0.0366);
  52. foreach (var element in wandImages.ImageList)
  53. {
  54. using (var blackPixelWand = new PixelWand(ColorName.Black))
  55. {
  56. int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
  57. element.Gravity = GravityType.CenterGravity;
  58. element.BackgroundColor = blackPixelWand;
  59. element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
  60. int ix = (int)Math.Abs((iWidth - iSlice) / 2);
  61. element.CropImage(iSlice, iHeight, ix, 0);
  62. element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
  63. }
  64. }
  65. wandImages.SetFirstIterator();
  66. using (var wandList = wandImages.AppendImages())
  67. {
  68. wandList.CurrentImage.TrimImage(1);
  69. using (var mwr = wandList.CloneMagickWand())
  70. {
  71. using (var blackPixelWand = new PixelWand(ColorName.Black))
  72. {
  73. using (var greyPixelWand = new PixelWand(ColorName.Grey70))
  74. {
  75. mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
  76. mwr.CurrentImage.FlipImage();
  77. mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
  78. mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
  79. using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
  80. {
  81. mwg.OpenImage("gradient:black-none");
  82. var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
  83. mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.CopyOpacityCompositeOp, 0, verticalSpacing);
  84. wandList.AddImage(mwr);
  85. int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
  86. wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .05));
  87. }
  88. }
  89. }
  90. }
  91. }
  92. }
  93. return wand;
  94. }
  95. }
  96. private MagickWand BuildThumbCollageWand(string[] paths, int width, int height)
  97. {
  98. var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
  99. using (var wandImages = new MagickWand(inputPaths.ToArray()))
  100. {
  101. var wand = new MagickWand(width, height);
  102. wand.OpenImage("gradient:#111111-#111111");
  103. using (var draw = new DrawingWand())
  104. {
  105. var iSlice = Convert.ToInt32(width * 0.24125);
  106. int iTrans = Convert.ToInt32(height * .25);
  107. int iHeight = Convert.ToInt32(height * .70);
  108. var horizontalImagePadding = Convert.ToInt32(width * 0.0125);
  109. foreach (var element in wandImages.ImageList)
  110. {
  111. using (var blackPixelWand = new PixelWand(ColorName.Black))
  112. {
  113. int iWidth = (int)Math.Abs(iHeight * element.Width / element.Height);
  114. element.Gravity = GravityType.CenterGravity;
  115. element.BackgroundColor = blackPixelWand;
  116. element.ResizeImage(iWidth, iHeight, FilterTypes.LanczosFilter);
  117. int ix = (int)Math.Abs((iWidth - iSlice) / 2);
  118. element.CropImage(iSlice, iHeight, ix, 0);
  119. element.ExtentImage(iSlice, iHeight, 0 - horizontalImagePadding, 0);
  120. }
  121. }
  122. wandImages.SetFirstIterator();
  123. using (var wandList = wandImages.AppendImages())
  124. {
  125. wandList.CurrentImage.TrimImage(1);
  126. using (var mwr = wandList.CloneMagickWand())
  127. {
  128. using (var blackPixelWand = new PixelWand(ColorName.Black))
  129. {
  130. using (var greyPixelWand = new PixelWand(ColorName.Grey70))
  131. {
  132. mwr.CurrentImage.ResizeImage(wandList.CurrentImage.Width, (wandList.CurrentImage.Height / 2), FilterTypes.LanczosFilter, 1);
  133. mwr.CurrentImage.FlipImage();
  134. mwr.CurrentImage.AlphaChannel = AlphaChannelType.DeactivateAlphaChannel;
  135. mwr.CurrentImage.ColorizeImage(blackPixelWand, greyPixelWand);
  136. using (var mwg = new MagickWand(wandList.CurrentImage.Width, iTrans))
  137. {
  138. mwg.OpenImage("gradient:black-none");
  139. var verticalSpacing = Convert.ToInt32(height * 0.01111111111111111111111111111111);
  140. mwr.CurrentImage.CompositeImage(mwg, CompositeOperator.CopyOpacityCompositeOp, 0, verticalSpacing);
  141. wandList.AddImage(mwr);
  142. int ex = (int)(wand.CurrentImage.Width - mwg.CurrentImage.Width) / 2;
  143. wand.CurrentImage.CompositeImage(wandList.AppendImages(true), CompositeOperator.AtopCompositeOp, ex, Convert.ToInt32(height * .045));
  144. }
  145. }
  146. }
  147. }
  148. }
  149. }
  150. return wand;
  151. }
  152. }
  153. private MagickWand BuildSquareCollageWand(string[] paths, int width, int height)
  154. {
  155. var inputPaths = ImageHelpers.ProjectPaths(paths, 4);
  156. var outputWand = new MagickWand(width, height, new PixelWand("none", 1));
  157. var imageIndex = 0;
  158. var cellWidth = width/2;
  159. var cellHeight = height/2;
  160. for (var x = 0; x < 2; x++)
  161. {
  162. for (var y = 0; y < 2; y++)
  163. {
  164. using (var temp = new MagickWand(inputPaths[imageIndex]))
  165. {
  166. temp.CurrentImage.ScaleImage(cellWidth, cellHeight);
  167. // draw this image into the strip at the next position
  168. var xPos = x*cellWidth;
  169. var yPos = y*cellHeight;
  170. outputWand.CurrentImage.CompositeImage(temp, CompositeOperator.OverCompositeOp, xPos, yPos);
  171. }
  172. imageIndex++;
  173. }
  174. }
  175. return outputWand;
  176. }
  177. }
  178. }