ImageWatermarker.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Text;
  4. using System.IO;
  5. using Masuit.Tools.Systems;
  6. namespace Masuit.Tools.Media
  7. {
  8. public class ImageWatermarker
  9. {
  10. /// <summary>
  11. /// 是否跳过小缩略图
  12. /// </summary>
  13. public bool SkipWatermarkForSmallImages { get; set; }
  14. /// <summary>
  15. /// 小图像素大小
  16. /// </summary>
  17. public int SmallImagePixelsThreshold { get; set; }
  18. private readonly Stream _stream;
  19. public ImageWatermarker(Stream originStream)
  20. {
  21. _stream = originStream;
  22. }
  23. /// <summary>
  24. /// 添加水印
  25. /// </summary>
  26. /// <param name="watermarkText">水印文字</param>
  27. /// <param name="color">水印颜色</param>
  28. /// <param name="watermarkPosition">水印位置</param>
  29. /// <param name="textPadding">边距</param>
  30. /// <param name="fontSize">字体大小</param>
  31. /// <param name="font">字体</param>
  32. /// <param name="textAntiAlias">不提示的情况下使用抗锯齿标志符号位图来绘制每个字符。
  33. /// 由于抗锯齿质量就越好。
  34. /// 因为关闭了提示,词干宽度之间的差异可能非常明显。</param>
  35. /// <returns></returns>
  36. public PooledMemoryStream AddWatermark(string watermarkText, Color color, WatermarkPosition watermarkPosition = WatermarkPosition.BottomRight, int textPadding = 10, int fontSize = 20, Font font = null, bool textAntiAlias = true)
  37. {
  38. using var img = Image.FromStream(_stream);
  39. if (SkipWatermarkForSmallImages && (img.Height < Math.Sqrt(SmallImagePixelsThreshold) || img.Width < Math.Sqrt(SmallImagePixelsThreshold)))
  40. {
  41. return _stream.SaveAsMemoryStream();
  42. }
  43. using var graphic = Graphics.FromImage(img);
  44. if (textAntiAlias)
  45. {
  46. graphic.TextRenderingHint = TextRenderingHint.AntiAlias;
  47. }
  48. using var brush = new SolidBrush(color);
  49. if (img.Width / fontSize > 50)
  50. {
  51. fontSize = img.Width / 50;
  52. }
  53. using var f = font ?? new Font(FontFamily.GenericSansSerif, fontSize, FontStyle.Bold, GraphicsUnit.Pixel);
  54. var textSize = graphic.MeasureString(watermarkText, f);
  55. int x, y;
  56. textPadding += (img.Width - 1000) / 100;
  57. switch (watermarkPosition)
  58. {
  59. case WatermarkPosition.TopLeft:
  60. x = textPadding;
  61. y = textPadding;
  62. break;
  63. case WatermarkPosition.TopRight:
  64. x = img.Width - (int)textSize.Width - textPadding;
  65. y = textPadding;
  66. break;
  67. case WatermarkPosition.BottomLeft:
  68. x = textPadding;
  69. y = img.Height - (int)textSize.Height - textPadding;
  70. break;
  71. case WatermarkPosition.BottomRight:
  72. x = img.Width - (int)textSize.Width - textPadding;
  73. y = img.Height - (int)textSize.Height - textPadding;
  74. break;
  75. default:
  76. x = textPadding;
  77. y = textPadding;
  78. break;
  79. }
  80. graphic.DrawString(watermarkText, f, brush, new Point(x, y));
  81. var ms = new PooledMemoryStream();
  82. img.Save(ms, img.RawFormat);
  83. ms.Position = 0;
  84. return ms;
  85. }
  86. }
  87. }