using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Common
{
public class ImageHelper
{
/// <summary>
/// 生成图片,采用等比例压缩方式
/// </summary>
/// <param name="imgBytes">源图片字节流</param>
/// <param name="width">新图片宽度</param>
/// <param name="height">新图片高度</param>
/// <param name="makeMode">生成模式</param>
/// <returns>生成后的图片流</returns>
public static byte[] MakeImage(byte[] imgBytes, int width, int height, ImageMakeMode makeMode)
{
return MakeImage(BytesToImage(imgBytes), width, height, makeMode);
}
/// <summary>
/// 生成图片,采用等比例压缩方式
/// </summary>
/// <param name="originalImage">源图片</param>
/// <param name="width">新图片宽度</param>
/// <param name="height">新图片高度</param>
/// <param name="makeMode">生成模式</param>
/// <returns>生成后的图片流</returns>
public static byte[] MakeImage(Image originalImage, int width, int height, ImageMakeMode makeMode)
{
byte[] bytes;
// 生成的新图实际宽度及高度
int towidth = width;
int toheight = height;
//新图在画布上的位置
int x = 0;
int y = 0;
//要绘制的原图宽高
int ow = originalImage.Width;
int oh = originalImage.Height;
if (makeMode == ImageMakeMode.KeepRatio)
{
ImageSize size = GetImageSize(originalImage.Width, originalImage.Height, width, height);
towidth = (int)size.ImageWidth;
toheight = (int)size.ImageHeight;
}
else
{
// 根据原图及欲生成的新图尺寸,计算新图的实际尺寸及其在"画布"上的位置
if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
{
oh = originalImage.Height;
ow = originalImage.Height * towidth / toheight;
y = 0;
x = (originalImage.Width - ow) / 2;
}
else
{
ow = originalImage.Width;
oh = originalImage.Width * height / towidth;
x = 0;
y = (originalImage.Height - oh) / 2;
}
}
Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
Graphics g = System.Drawing.Graphics.FromImage(bitmap);
try
{
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.Clear(Color.Transparent);
g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
new Rectangle(x, y, ow, oh),
GraphicsUnit.Pixel);
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, originalImage.RawFormat);
bytes = ms.ToArray();
}
}
catch (System.Exception e)
{
throw e;
}
finally
{
originalImage.Dispose();
bitmap.Dispose();
g.Dispose();
}
return bytes;
}
/// <summary>
/// 生成图片,采用等比例压缩方式
/// </summary>
/// <param name="sourceImgPath">源图片路径</param>
/// <param name="saveImgPath">新图片路径</param>
/// <param name="width">新图片宽度</param>
/// <param name="height">新图片高度</param>
/// <param name="makeMode">生成模式</param>
/// <returns></returns>
public static bool MakeImage(string sourceImgPath, string saveImgPath, int width, int height, ImageMakeMode makeMode)
{
byte[] bytes = MakeImage(Image.FromFile(sourceImgPath), width, height, makeMode);
using (FileStream stream = new FileStream(saveImgPath, FileMode.Create))
{
stream.Write(bytes, 0, bytes.Length);
}
bytes = null;
return true;
}
/// <summary>
/// 图片转换 Byte[] to Image
/// </summary>
/// <param name="buffer">byte[]</param>
/// <returns></returns>
public static Image BytesToImage(byte[] buffer)
{
Image image = null;
if (buffer != null)
{
using (MemoryStream ms = new MemoryStream(buffer))
{
image = System.Drawing.Image.FromStream(ms);
}
}
return image;
}
/// <summary>
/// 图片转换 Image to Byte[]
/// </summary>
/// <param name="img">Image</param>
/// <returns></returns>
public static Byte[] ImageToBytes(Image img)
{
byte[] bytes;
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, img.RawFormat);
bytes = ms.ToArray();
}
return bytes;
}
/// <summary>
/// 获取一个图片按等比例缩小后的大小。
/// </summary>
/// <param name="imgWidth"></param>
/// <param name="imgHeight"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
/// <returns></returns>
public static ImageSize GetImageSize(double imgWidth, double imgHeight, double maxWidth, double maxHeight)
{
ImageSize size = new ImageSize();
double exportWidth = imgWidth;
double exportHeight = imgHeight;
if (imgWidth > imgHeight) //如果宽度超过高度以宽度为准来压缩
{
if (imgWidth > maxWidth) //如果图片宽度超过限制
{
exportWidth = maxWidth; //图片压缩后的宽度
exportHeight = imgHeight / (double)(imgWidth / exportWidth); //图片压缩后的高度
}
}
else
{
if (imgHeight > maxHeight)
{
exportHeight = maxHeight;
exportWidth = imgWidth / (double)(imgHeight / exportHeight);
}
}
size.ImageWidth = exportWidth;
size.ImageHeight = exportHeight;
return size;
}
/// <summary>
/// 图片转换
/// </summary>
/// <param name="imagepath">图片路径</param>
/// <returns>byte[]二进制流</returns>
public static byte[] GetPictureData(string imagepath)
{
try
{
using (FileStream fs = new FileStream(imagepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
byte[] byData = new byte[fs.Length];
fs.Read(byData, 0, byData.Length);
fs.Close();
fs.Dispose();
return byData;
}
}
catch (Exception ex)
{
//图片转换异常
throw ex;
}
}
/// <summary>
/// 图片(流)加水印
/// </summary>
/// <param name="by">图片二进制流</param>
/// <param name="markText">水印文本</param>
/// <returns></returns>
public byte[] WaterMark(byte[] by, string markText)
{
MemoryStream ms = new MemoryStream(by);
Bitmap bitmap = (Bitmap)Image.FromStream(ms);
ms.Close();
WaterMark(bitmap, new ImageWaterMarkContext(markText)
{
Margin = new Padding(5),
TextBackColor = Color.Black,
TextForeColor = Color.AntiqueWhite,
TextBorderColor = Color.Transparent,
Opacity = 0.3F
});
MemoryStream mstream = new MemoryStream();
bitmap.Save(mstream, System.Drawing.Imaging.ImageFormat.Bmp);
bitmap.Dispose();
bitmap = null;
byte[] bytes = mstream.GetBuffer();
mstream.Close();
return bytes;
}
/// <summary>
/// 图片(流)加水印
/// </summary>
/// <param name="by">原图二进制流</param>
/// <param name="markImage">水印图二进制流</param>
/// <returns>byte[]二进制图片流</returns>
public byte[] WaterMark(byte[] by, byte[] markImage)
{
//原图(流转图像)
MemoryStream ms = new MemoryStream(by);
Bitmap bitmap = (Bitmap)Image.FromStream(ms);
ms.Close();
//水印图(流转图像)
MemoryStream markms = new MemoryStream(markImage);
Bitmap markbitmap = (Bitmap)Image.FromStream(markms);
markms.Close();
WaterMark(bitmap, new ImageWaterMarkContext(markbitmap)
{
Margin = new Padding(5),
TextBackColor = Color.Black,
TextForeColor = Color.AntiqueWhite,
TextBorderColor = Color.Transparent,
Opacity = 0.3F
});
MemoryStream mstream = new MemoryStream();
bitmap.Save(mstream, System.Drawing.Imaging.ImageFormat.Bmp);
bitmap.Dispose();
bitmap = null;
byte[] bytes = mstream.GetBuffer();
mstream.Close();
return bytes;
}
/// <summary>
/// 为图像加上水印(忽略gif格式)注:直接在原始图像上做处理。
/// </summary>
/// <param name="bitmap">需要处理的图像</param>
/// <param name="context">水印上下文实例</param>
public static void WaterMark(Bitmap bitmap, ImageWaterMarkContext context)
{
if (bitmap == null || context == null)
return;
//Gif不加水印的
if (bitmap.RawFormat == ImageFormat.Gif)
return;
float width;//水印宽
float height;//水印高
float x = 0F;//坐标.x
float y = 0F;//坐标.y
Graphics g = Graphics.FromImage(bitmap);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
Bitmap image = null;
if (context.Image != null)
{
//图像水印
width = context.Image.Width;
height = context.Image.Height;
image = context.Image;
}
else
{
//文本水印
if (context.TextFont == null)
context.TextFont = ImageWaterMarkContext.DefaultTextFont;
SizeF size = g.MeasureString(context.Text, context.TextFont);
width = size.Width + 6F;
height = size.Height + 6F;
image = new Bitmap((int)width, (int)height, PixelFormat.Format32bppArgb);
Graphics g2 = Graphics.FromImage(image);
g2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
if (context.TextBackColor == null)
context.TextBackColor = ImageWaterMarkContext.DefaultTextBackColor;
if (context.TextForeColor == null)
context.TextForeColor = ImageWaterMarkContext.DefaultTextForeColor;
if (context.TextBorderColor == null)
context.TextBorderColor = ImageWaterMarkContext.DefaultBorderColor;
g2.Clear(context.TextBackColor);
g2.DrawRectangle(new Pen(context.TextBorderColor, 1F), 0F, 0F, width - 2F, height - 2F);
g2.DrawString(context.Text, context.TextFont, new SolidBrush(context.TextForeColor), 3, 3);
g2.Dispose();
g2 = null;
}
//水印超出范围
if (width >= bitmap.Width || height >= bitmap.Height)
return;
//推算坐标
switch (context.Location)
{
case ImageWaterMarkLocation.TopLeft:
x = context.Margin.Left;
y = context.Margin.Top;
break;
case ImageWaterMarkLocation.TopCenter:
x = (bitmap.Width - width) / 2; y = context.Margin.Top;
break;
case ImageWaterMarkLocation.TopRight:
x = bitmap.Width - context.Margin.Right - width; y = context.Margin.Top;
break;
case ImageWaterMarkLocation.MiddleLeft:
x = context.Margin.Left; y = (bitmap.Height - height) / 2;
break;
case ImageWaterMarkLocation.MiddleCenter:
x = (bitmap.Width - width) / 2; y = (bitmap.Height - height) / 2;
break;
case ImageWaterMarkLocation.MiddleRight:
x = bitmap.Width - context.Margin.Right - width; y = (bitmap.Height - height) / 2;
break;
case ImageWaterMarkLocation.BottomLeft:
x = context.Margin.Left; y = bitmap.Height - height - context.Margin.Bottom;
break;
case ImageWaterMarkLocation.BottomCenter:
x = (bitmap.Width - width) / 2; y = bitmap.Height - height - context.Margin.Bottom;
break;
case ImageWaterMarkLocation.BottomRight:
x = bitmap.Width - context.Margin.Right - width; y = bitmap.Height - height - context.Margin.Bottom;
break;
}
//图像水印
image.SetResolution(bitmap.HorizontalResolution, bitmap.VerticalResolution);
ImageAttributes imageAttributes = new ImageAttributes();
imageAttributes.SetRemapTable(new ColorMap[]{
new ColorMap(){
OldColor= Color.FromArgb(255,0,255,0),
NewColor= Color.FromArgb(0,0,0,0),
}
}, ColorAdjustType.Bitmap);
if (context.Opacity < 0F || context.Opacity > 1F)
context.Opacity = 0.51F;
imageAttributes.SetColorMatrix(new ColorMatrix(new float[][]{
new float[]{1.0F,0.0F,0.0F,0.0F,0.0F},
new float[]{0.0F,1.0F,0.0F,0.0F,0.0F},
new float[]{0.0F,0.0F,1.0F,0.0F,0.0F},
new float[]{0.0F,0.0F,0.0F,context.Opacity,0.0F},//65透明度
new float[]{0.0F,0.0F,0.0F,0.0F,1.0F},
}), ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
g.DrawImage(image, new Rectangle((int)x, (int)y, (int)width, (int)height), 0, 0, width, height, GraphicsUnit.Pixel, imageAttributes);
g.Dispose();
g = null;
if (context.Image == null)
{
image.Dispose();
image = null;
}
}
}
/// <summary>
/// 等比率生成图片模式
/// </summary>
public enum ImageMakeMode
{
/// <summary>
/// 固定尺寸,按照指定宽高生成
/// </summary>
KeepSize = 0,
/// <summary>
/// 固定比例,按照原图比例生成,新图宽高在指定宽高范围内
/// </summary>
KeepRatio = 1
}
/// <summary>
/// 图像水印位置集
/// </summary>
public enum ImageWaterMarkLocation
{
/// <summary>
/// 上-左
/// </summary>
TopLeft,
/// <summary>
/// 上-中
/// </summary>
TopCenter,
/// <summary>
/// 上-右
/// </summary>
TopRight,
/// <summary>
/// 中-左
/// </summary>
MiddleLeft,
/// <summary>
/// 中-中
/// </summary>
MiddleCenter,
/// <summary>
/// 中-右
/// </summary>
MiddleRight,
/// <summary>
/// 下-左
/// </summary>
BottomLeft,
/// <summary>
/// 下-中
/// </summary>
BottomCenter,
/// <summary>
/// 下-右
/// </summary>
BottomRight,
}
/// <summary>
/// 图片尺寸
/// </summary>
public class ImageSize
{
/// <summary>
/// 宽
/// </summary>
public double ImageWidth { get; set; }
/// <summary>
/// 高
/// </summary>
public double ImageHeight { get; set; }
}
/// <summary>
/// 水印上下文类
/// </summary>
public class ImageWaterMarkContext
{
/// <summary>
/// 默认边缘距离(5像素)
/// </summary>
public static readonly Padding DefaultMargin = new Padding(5);
/// <summary>
/// 默认文本字体(Arial,18号,粗体)
/// </summary>
public static readonly Font DefaultTextFont = new Font("楷体", 18F, FontStyle.Regular, GraphicsUnit.Pixel);
/// <summary>
/// 默认文本背景颜色(Color.WhiteSmoke,雾白色)
/// </summary>
public static readonly Color DefaultTextBackColor = Color.WhiteSmoke;
/// <summary>
/// 默认文本前景颜色(Color.Black,黑色)
/// </summary>
public static readonly Color DefaultTextForeColor = Color.Black;
/// <summary>
/// 默认文本边框颜色(Color.DimGray,暗灰色)
/// </summary>
public static readonly Color DefaultBorderColor = Color.DimGray;
/// <summary>
/// 水印位置
/// </summary>
public ImageWaterMarkLocation Location { get; set; }
/// <summary>
/// 边缘距离(单位:像素)
/// </summary>
public Padding Margin { get; set; }
/// <summary>
/// 文本水印
/// </summary>
public string Text { get; private set; }
/// <summary>
/// 文本字体
/// </summary>
public Font TextFont { get; set; }
/// <summary>
/// 文本背景颜色
/// </summary>
public Color TextBackColor { get; set; }
/// <summary>
/// 文本前景颜色
/// </summary>
public Color TextForeColor { get; set; }
/// <summary>
/// 文本边框颜色
/// </summary>
public Color TextBorderColor { get; set; }
/// <summary>
/// 透明度,默认是 0.51,即51的透明度,有效值0.00F-1.00F,值越大越不透明。
/// </summary>
public float Opacity { get; set; }
/// <summary>
/// 图像水印
/// </summary>
public Bitmap Image { get; private set; }
/// <summary>
/// 创建水印上下文实例(文本水印)
/// </summary>
/// <param name="text">文本水印</param>
/// <param name="location">水印位置,默认为下-右</param>
public ImageWaterMarkContext(string text, ImageWaterMarkLocation location = ImageWaterMarkLocation.BottomRight)
: this(location)
{
if (string.IsNullOrEmpty(text))
throw new ArgumentNullException("text", "文本水印内容不能为null或“”。");
Text = text;
}
/// <summary>
/// 创建水印上下文实例(图像水印)
/// </summary>
/// <param name="image">图像水印</param>
/// <param name="location">水印位置,默认为下-右</param>
public ImageWaterMarkContext(Bitmap image, ImageWaterMarkLocation location = ImageWaterMarkLocation.BottomRight)
: this(location)
{
if (image == null)
throw new ArgumentNullException("image", "图像水印不能为null。");
Image = image;
}
/// <summary>
/// 默认值
/// </summary>
/// <param name="location">水印位置</param>
private ImageWaterMarkContext(ImageWaterMarkLocation location)
{
Location = location;
Margin = DefaultMargin;
TextFont = DefaultTextFont;
TextBackColor = TextBackColor;
TextForeColor = DefaultTextForeColor;
TextBorderColor = DefaultBorderColor;
Opacity = 0.51F;
}
}
}