StripCollageBuilder.cs 9.3 KB

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