函数封装的相关功能
如题目所说,可自定义文字透明度及位置
传入的图片参数byte[]与Image的转换本文下面也进行了封装,如需修改传入的参数可自行进行转换
如果没传入文本,则文本利用GUID生成随机字符
调用
Cyf.ImageUtility.PictureHelper. DrawWaterText(bytes);
代码
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
namespace Cyf.ImageUtility
{
public class PictureHelper
{
/// <summary>
/// 给图片加入文字水印,且设置水印透明度
/// </summary>
/// <param name="destPath">保存地址</param>
/// <param name="srcPath">源文件地址,如果想覆盖源图片,两个地址参数一定要一样</param>
/// <param name="text">文字</param>
/// <param name="font">字体,为空则使用默认,注意,在创建字体时 GraphicsUnit.Pixel </param>
/// <param name="brush">刷子,为空则使用默认</param>
/// <param name="pos">设置水印位置,1左上,2中上,3右上
/// 4左中,5中, 6右中
/// 7左下,8中下,9右下</param>
/// <param name="padding">跟css里的padding一个意思</param>
/// <param name="quality">1~100整数,无效值,则取默认值95</param>
/// <param name="opcity">不透明度 100 为完全不透明,0为完全透明</param>
public static byte[] DrawWaterText(byte[] imgBytes, string text = "", Font font = null, Brush brush = null, int pos = 9, int quality = 95, int opcity = 60, string mimeType = "image/jpeg")
{
int padding = 10;
Image srcImage = null;
Image destImage = null;
Graphics graphics = null;
byte[] resultByte = null;
if (string.IsNullOrEmpty(text))
{
text = Guid.NewGuid().ToString("N").Substring(0, 10);
}
if (font == null)
{
font = new Font("微软雅黑", 20, FontStyle.Bold, GraphicsUnit.Pixel);//统一尺寸
}
if (brush == null)
{
brush = new SolidBrush(Color.White);
}
try
{
//获取源图像
srcImage = BytesToImage(imgBytes);
//定义画布,大小与源图像一样
destImage = new Bitmap(srcImage);
//获取高清Graphics
graphics = GetGraphics(destImage);
//将源图像画到画布上,注意最后一个参数GraphicsUnit.Pixel
graphics.DrawImage(srcImage, new Rectangle(0, 0, destImage.Width, destImage.Height), new Rectangle(0, 0, srcImage.Width, srcImage.Height), GraphicsUnit.Pixel);
//如果水印字不为空,且不透明度大于0,则画水印
if (!string.IsNullOrEmpty(text) && opcity > 0)
{
//获取可以用来绘制水印图片的有效区域
Rectangle validRect = new Rectangle(padding, padding, srcImage.Width - padding * 2, srcImage.Height - padding * 2);
//获取绘画水印文字的格式,即文字对齐方式
StringFormat format = GetStringFormat(pos);
//如果不透明度==100,那么直接将字画到当前画布上.
if (opcity == 100)
{
graphics.DrawString(text, font, brush, validRect, format);
}
else
{
//如果不透明度在0到100之间,就要实现透明效果,文字没法透明,图片才能透明
//则先将字画到一块临时画布,临时画布与destImage一样大,先将字写到这块画布上,再将临时画布画到主画布上,同时设置透明参数
Bitmap transImg = null;
Graphics gForTransImg = null;
try
{
//定义临时画布
transImg = new Bitmap(destImage);
//获取高清Graphics
gForTransImg = GetGraphics(transImg);
//绘制文字
gForTransImg.DrawString(text, font, brush, validRect, format);
//**获取带有透明度的ImageAttributes
ImageAttributes imageAtt = GetAlphaImgAttr(opcity);
//将这块临时画布画在主画布上
graphics.DrawImage(transImg, new Rectangle(0, 0, destImage.Width, destImage.Height), 0, 0, transImg.Width, transImg.Height, GraphicsUnit.Pixel, imageAtt);
}
catch{ }
finally
{
if (transImg != null)
transImg.Dispose();
if (gForTransImg != null)
gForTransImg.Dispose();
}
}
}
resultByte = ImageToBytes(destImage);
}
catch { }
finally
{
if (srcImage != null)
srcImage.Dispose();
if (destImage != null)
destImage.Dispose();
if (graphics != null)
graphics.Dispose();
}
return resultByte;
}
/// <summary>
/// 获取高清的Graphics
/// </summary>
/// <param name="img"></param>
/// <returns></returns>
private static Graphics GetGraphics(Image img)
{
var g = Graphics.FromImage(img);
//设置质量
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
//InterpolationMode不能使用High或者HighQualityBicubic,如果是灰色或者部分浅色的图像是会在边缘处出一白色透明的线
//用HighQualityBilinear却会使图片比其他两种模式模糊(需要肉眼仔细对比才可以看出)
g.InterpolationMode = InterpolationMode.Default;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
return g;
}
/// <summary>
/// 获取文字水印位置
/// </summary>
/// <param name="pos">
/// 1左上,2中上,3右上
/// 4左中,5中, 6右中
/// 7左下,8中下,9右下
/// </param>
/// <returns></returns>
private static StringFormat GetStringFormat(int pos)
{
StringFormat format = new StringFormat();
switch (pos)
{
case 1: format.Alignment = StringAlignment.Near; format.LineAlignment = StringAlignment.Near; break;
case 2: format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Near; break;
case 3: format.Alignment = StringAlignment.Far; format.LineAlignment = StringAlignment.Near; break;
case 4: format.Alignment = StringAlignment.Near; format.LineAlignment = StringAlignment.Center; break;
case 6: format.Alignment = StringAlignment.Far; format.LineAlignment = StringAlignment.Center; break;
case 7: format.Alignment = StringAlignment.Near; format.LineAlignment = StringAlignment.Far; break;
case 8: format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Far; break;
case 9: format.Alignment = StringAlignment.Far; format.LineAlignment = StringAlignment.Far; break;
default: format.Alignment = StringAlignment.Center; format.LineAlignment = StringAlignment.Center; break;
}
return format;
}
/// <summary>
/// 获取一个带有透明度的ImageAttributes
/// </summary>
/// <param name="opcity"></param>
/// <returns></returns>
private static ImageAttributes GetAlphaImgAttr(int opcity)
{
if (opcity < 0 || opcity > 100)
{
throw new ArgumentOutOfRangeException("opcity 值为 0~100");
}
//颜色矩阵
float[][] matrixItems =
{
new float[]{1,0,0,0,0},
new float[]{0,1,0,0,0},
new float[]{0,0,1,0,0},
new float[]{0,0,0,(float)opcity / 100,0},
new float[]{0,0,0,0,1}
};
ColorMatrix colorMatrix = new ColorMatrix(matrixItems);
ImageAttributes imageAtt = new ImageAttributes();
imageAtt.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
return imageAtt;
}
/// <summary>
/// Convert Image to Byte[]
/// </summary>
/// <param name="image"></param>
/// <returns></returns>
public static byte[] ImageToBytes(Image image)
{
ImageFormat format = image.RawFormat;
using (MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Jpeg);
byte[] buffer = new byte[ms.Length];
//Image.Save()会改变MemoryStream的Position,需要重新Seek到Begin
ms.Seek(0, SeekOrigin.Begin);
ms.Read(buffer, 0, buffer.Length);
return buffer;
}
}
/// <summary>
/// Convert Byte[] to Image
/// </summary>
/// <param name="buffer"></param>
/// <returns></returns>
public static Image BytesToImage(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer);
Image image = System.Drawing.Image.FromStream(ms);
return image;
}
}
}