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