2
0

ImageProcessor.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Drawing2D;
  4. using System.Drawing.Imaging;
  5. using System.IO;
  6. namespace MediaBrowser.Api
  7. {
  8. public static class ImageProcessor
  9. {
  10. public static void ProcessImage(Stream sourceImageStream, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality)
  11. {
  12. Image originalImage = Image.FromStream(sourceImageStream);
  13. var newWidth = originalImage.Width;
  14. var newHeight = originalImage.Height;
  15. if (width.HasValue && height.HasValue)
  16. {
  17. newWidth = width.Value;
  18. newHeight = height.Value;
  19. }
  20. else if (height.HasValue)
  21. {
  22. newWidth = GetNewWidth(newHeight, newWidth, height.Value);
  23. newHeight = height.Value;
  24. }
  25. else if (width.HasValue)
  26. {
  27. newHeight = GetNewHeight(newHeight, newWidth, width.Value);
  28. newWidth = width.Value;
  29. }
  30. if (maxHeight.HasValue && maxHeight < newHeight)
  31. {
  32. newWidth = GetNewWidth(newHeight, newWidth, maxHeight.Value);
  33. newHeight = maxHeight.Value;
  34. }
  35. if (maxWidth.HasValue && maxWidth < newWidth)
  36. {
  37. newHeight = GetNewHeight(newHeight, newWidth, maxWidth.Value);
  38. newWidth = maxWidth.Value;
  39. }
  40. Bitmap thumbnail = new Bitmap(newWidth, newHeight, originalImage.PixelFormat);
  41. thumbnail.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);
  42. Graphics thumbnailGraph = Graphics.FromImage(thumbnail);
  43. thumbnailGraph.CompositingQuality = CompositingQuality.HighQuality;
  44. thumbnailGraph.SmoothingMode = SmoothingMode.HighQuality;
  45. thumbnailGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
  46. thumbnailGraph.PixelOffsetMode = PixelOffsetMode.HighQuality;
  47. thumbnailGraph.CompositingMode = CompositingMode.SourceOver;
  48. thumbnailGraph.DrawImage(originalImage, 0, 0, newWidth, newHeight);
  49. Write(originalImage, thumbnail, toStream, quality);
  50. thumbnailGraph.Dispose();
  51. thumbnail.Dispose();
  52. originalImage.Dispose();
  53. }
  54. private static void Write(Image originalImage, Image newImage, Stream toStream, int? quality)
  55. {
  56. // Use special save methods for jpeg and png that will result in a much higher quality image
  57. // All other formats use the generic Image.Save
  58. if (ImageFormat.Jpeg.Equals(originalImage.RawFormat))
  59. {
  60. SaveJpeg(newImage, toStream, quality);
  61. }
  62. else if (ImageFormat.Png.Equals(originalImage.RawFormat))
  63. {
  64. SavePng(newImage, toStream);
  65. }
  66. else
  67. {
  68. newImage.Save(toStream, originalImage.RawFormat);
  69. }
  70. }
  71. private static void SaveJpeg(Image newImage, Stream target, int? quality)
  72. {
  73. if (!quality.HasValue)
  74. {
  75. quality = 90;
  76. }
  77. using (EncoderParameters encoderParameters = new EncoderParameters(1))
  78. {
  79. encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality.Value);
  80. newImage.Save(target, GetImageCodeInfo("image/jpeg"), encoderParameters);
  81. }
  82. }
  83. private static void SavePng(Image newImage, Stream target)
  84. {
  85. if (target.CanSeek)
  86. {
  87. newImage.Save(target, ImageFormat.Png);
  88. }
  89. else
  90. {
  91. using (MemoryStream ms = new MemoryStream(4096))
  92. {
  93. newImage.Save(ms, ImageFormat.Png);
  94. ms.WriteTo(target);
  95. }
  96. }
  97. }
  98. private static ImageCodecInfo GetImageCodeInfo(string mimeType)
  99. {
  100. ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
  101. for (int i = 0; i < info.Length; i++)
  102. {
  103. ImageCodecInfo ici = info[i];
  104. if (ici.MimeType.Equals(mimeType, StringComparison.OrdinalIgnoreCase))
  105. {
  106. return ici;
  107. }
  108. }
  109. return info[1];
  110. }
  111. private static int GetNewWidth(int currentHeight, int currentWidth, int newHeight)
  112. {
  113. decimal scaleFactor = newHeight;
  114. scaleFactor /= currentHeight;
  115. scaleFactor *= currentWidth;
  116. return Convert.ToInt32(scaleFactor);
  117. }
  118. private static int GetNewHeight(int currentHeight, int currentWidth, int newWidth)
  119. {
  120. decimal scaleFactor = newWidth;
  121. scaleFactor /= currentWidth;
  122. scaleFactor *= currentHeight;
  123. return Convert.ToInt32(scaleFactor);
  124. }
  125. }
  126. }