using System;
|
using System.Collections.Generic;
|
using System.Drawing;
|
using System.Drawing.Drawing2D;
|
using System.Drawing.Imaging;
|
using System.IO;
|
using System.Linq;
|
using System.Text;
|
|
namespace TProduct.Extensions
|
{
|
/// <summary>
|
/// Image 拓展
|
/// </summary>
|
public static class ImageExtension
|
{
|
/// <summary>
|
/// 获取索引像素格式数组
|
/// </summary>
|
internal static PixelFormat[] IndexedPixelFormats
|
{
|
get
|
{
|
return new PixelFormat[]
|
{
|
PixelFormat.Undefined,
|
PixelFormat.DontCare,
|
PixelFormat.Format16bppArgb1555,
|
PixelFormat.Format16bppGrayScale,
|
PixelFormat.Format1bppIndexed,
|
PixelFormat.Format4bppIndexed,
|
PixelFormat.Format8bppIndexed
|
};
|
}
|
}
|
|
/// <summary>
|
/// 是否为索引像素格式
|
/// </summary>
|
internal static bool IsPixelFormatIndexed(PixelFormat format)
|
{
|
if (IndexedPixelFormats.Contains(format))
|
return true;
|
return false;
|
}
|
|
/// <summary>
|
/// 是否为索引像素格式
|
/// </summary>
|
public static bool IsPixelFormatIndexed(this Image img)
|
{
|
return IsPixelFormatIndexed(img.PixelFormat);
|
}
|
|
/// <summary>
|
/// 自定义创建图片的副本(若PixelFormat为索引像素格式会抛异常))
|
/// </summary>
|
public static Image CloneC(this Image img, PixelFormat format = PixelFormat.Format32bppArgb)
|
{
|
if (!IsPixelFormatIndexed(img.PixelFormat))
|
{
|
format = img.PixelFormat;
|
}
|
var bmp = new Bitmap(img.Width, img.Height, format);
|
using (var g = Graphics.FromImage(bmp))
|
{
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
g.SmoothingMode = SmoothingMode.HighQuality;
|
g.CompositingQuality = CompositingQuality.HighQuality;
|
g.DrawImage(img, new Rectangle(0, 0, bmp.Width, bmp.Height));
|
}
|
return bmp;
|
}
|
|
/// <summary>
|
/// 绘制成椭圆图片
|
/// </summary>
|
public static Image CutEllipse(this Image img, Size size)
|
{
|
var bitmap = new Bitmap(size.Width, size.Height);
|
using (var g = Graphics.FromImage(bitmap))
|
{
|
using (TextureBrush br = new TextureBrush(img, WrapMode.Clamp, new Rectangle(Point.Empty, img.Size)))
|
{
|
br.ScaleTransform(bitmap.Width / (float)img.Width, bitmap.Height / (float)img.Height);
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
g.FillEllipse(br, new Rectangle(Point.Empty, size));
|
}
|
}
|
return bitmap;
|
}
|
|
/// <summary>
|
///自定义为图片生成缩略图
|
/// </summary>
|
public static Image GetThumbnailC(this Image img, int width, int height)
|
{
|
Bitmap bmp = new Bitmap(width, height);
|
using (var g = Graphics.FromImage(bmp))
|
{
|
g.SmoothingMode = SmoothingMode.HighQuality;
|
g.CompositingQuality = CompositingQuality.HighQuality;
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
g.DrawImage(img, new Rectangle(Point.Empty, bmp.Size));
|
}
|
return bmp;
|
}
|
|
/// <summary>
|
/// 自定义为图片生成缩略图
|
/// </summary>
|
public static Image GetThumbnailC(this Image img, Size size)
|
{
|
return GetThumbnailC(img, size.Width, size.Height);
|
}
|
|
/// <summary>
|
/// 通过系统新建生成缩略图
|
/// </summary>
|
public static Image GetThumbnailN(this Image img, Size size)
|
{
|
return new Bitmap(img, size);
|
}
|
|
/// <summary>
|
/// 通过过系统新建生成缩略图
|
/// </summary>
|
public static Image GetThumbnailN(this Image img, int width, int height)
|
{
|
return new Bitmap(img, width, height);
|
}
|
|
/// <summary>
|
/// 调用系统方法生成缩略图
|
/// </summary>
|
public static Image GetThumbnailS(this Image img, Size size)
|
{
|
return img.GetThumbnailImage(size.Width, size.Height, null, System.IntPtr.Zero);
|
}
|
|
/// <summary>
|
/// 调用系统方法生成缩略图
|
/// </summary>
|
public static Image GetThumbnailS(this Image img, int width, int height)
|
{
|
return img.GetThumbnailImage(width, height, null, System.IntPtr.Zero);
|
}
|
|
/// <summary>
|
/// 在图片上绘制文字信息(图片像素格式不能为像素索引格式)
|
/// </summary>
|
/// <param name="g">绘制文字的图片</param>
|
/// <param name="text">文本信息</param>
|
/// <param name="pf">定位点</param>
|
/// <param name="f">字体</param>
|
/// <param name="fc">字体颜色</param>
|
/// <param name="horiz">水平对齐方式</param>
|
/// <param name="verti">垂直对齐方式</param>
|
/// <param name="angle">旋转角度(顺时针)</param>
|
public static void DrawString(this Graphics g, string text, PointF pf, Font f, Color fc, float angle = 0, StringAlignment horiz = StringAlignment.Near, StringAlignment verti = StringAlignment.Near)
|
{
|
using (var brush = new SolidBrush(fc))
|
using (var format = new StringFormat())
|
{
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
g.TranslateTransform(pf.X, pf.Y);
|
g.RotateTransform(angle);
|
format.Alignment = horiz;
|
format.LineAlignment = verti;
|
g.DrawString(text, f, brush, new PointF(0, 0), format);
|
g.ResetTransform();
|
}
|
}
|
|
/// <summary>
|
/// 绘制文字信息(图片像素格式不能为像素索引格式)
|
/// </summary>
|
/// <param name="g"></param>
|
/// <param name="text"></param>
|
/// <param name="op">原点</param>
|
/// <param name="pf">文字依据的点</param>
|
/// <param name="fc">文字颜色</param>
|
/// <param name="angle">旋转角度</param>
|
/// <param name="horiz"></param>
|
/// <param name="verti"></param>
|
public static void DrawString(this Graphics g, string text, PointF op, SizeF size, Font f, Color fc, float angle = 0, StringAlignment align = StringAlignment.Near, StringAlignment vlign = StringAlignment.Center)
|
{
|
using (var brush = new SolidBrush(fc))
|
using (var format = new StringFormat())
|
{
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
g.TranslateTransform(op.X, op.Y);
|
g.RotateTransform(angle);
|
format.Alignment = align;
|
format.LineAlignment = vlign;
|
g.DrawString(text, f, brush, new RectangleF(PointF.Empty, size), format);
|
g.ResetTransform();
|
}
|
}
|
|
/// <summary>
|
/// 绘制文字信息(图片像素格式不能为像素索引格式)
|
/// </summary>
|
/// <param name="g"></param>
|
/// <param name="text"></param>
|
/// <param name="op"></param>
|
/// <param name="recf"></param>
|
/// <param name="f"></param>
|
/// <param name="fc"></param>
|
/// <param name="angle"></param>
|
/// <param name="scaleX"></param>
|
/// <param name="scaleY"></param>
|
/// <param name="align"></param>
|
/// <param name="vlign"></param>
|
public static void DrawString(this Graphics g, string text, PointF op, RectangleF recf, Font f, Color fc, float angle = 0, float scaleX = 1f, float scaleY = 1f, StringAlignment align = StringAlignment.Near, StringAlignment vlign = StringAlignment.Center)
|
{
|
using (var brush = new SolidBrush(fc))
|
using (var format = new StringFormat())
|
{
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
g.TranslateTransform(op.X, op.Y);
|
g.RotateTransform(angle);
|
if (scaleX <= 0)
|
scaleX = 1f;
|
if (scaleY <= 0)
|
scaleY = 1f;
|
g.ScaleTransform(scaleX, scaleY);
|
format.Alignment = align;
|
format.LineAlignment = vlign;
|
var startPoint = new PointF(recf.X - op.X, recf.Y - op.Y);
|
startPoint = new PointF(startPoint.X / scaleX, startPoint.Y / scaleY);
|
var new_size = new SizeF(recf.Width / scaleX, recf.Height / scaleY);
|
g.DrawString(text, f, brush, new RectangleF(startPoint, new_size), format);
|
g.ResetTransform();
|
}
|
}
|
|
/// <summary>
|
/// 绘制图片
|
/// </summary>
|
/// <param name="g"></param>
|
/// <param name="img"></param>
|
/// <param name="pf"></param>
|
/// <param name="angle"></param>
|
/// <param name="?"></param>
|
/// <param name="horiz"></param>
|
/// <param name="verti"></param>
|
public static void DrawImage(this Graphics g, Image img, PointF pf, float angle, StringAlignment horiz = StringAlignment.Center, StringAlignment verti = StringAlignment.Center)
|
{
|
PointF p = new PointF();
|
switch (horiz)
|
{
|
case StringAlignment.Near: p.X = 0; break;
|
case StringAlignment.Center: p.X = -img.Width / 2; break;
|
case StringAlignment.Far: p.X = -img.Width; break;
|
default: break;
|
}
|
switch (verti)
|
{
|
case StringAlignment.Near: p.Y = 0; break;
|
case StringAlignment.Center: p.Y = -img.Height / 2; break;
|
case StringAlignment.Far: p.Y = -img.Height; break;
|
default: break;
|
}
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
g.TranslateTransform(pf.X, pf.Y);
|
g.RotateTransform(angle);
|
g.DrawImage(img, p);
|
g.ResetTransform();
|
}
|
|
/// <summary>
|
/// 绘制箭头
|
/// </summary>
|
/// <param name="g"></param>
|
/// <param name="pf">开始点</param>
|
/// <param name="angle">旋转角度</param>
|
/// <param name="lineWidth">箭头线宽</param>
|
/// <param name="arrowWidth">箭头宽度</param>
|
/// <param name="arrowLength">箭头长度</param>
|
/// <param name="ac">箭头颜色</param>
|
/// <param name="horiz"></param>
|
/// <param name="verti"></param>
|
public static void DrawArrow(this Graphics g, PointF pf, float angle, float lineWidth, float lineLength, Color lc, float arrowWidth, float arrowLength, Color ac)
|
{
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
g.TranslateTransform(pf.X, pf.Y);
|
g.RotateTransform(angle);
|
var halfLineWidth = lineWidth / 2;
|
var halfArrowWidth = arrowWidth / 2;
|
lineLength = lineLength - arrowLength;
|
|
var lp1 = new PointF(0, halfLineWidth);
|
var lp2 = new PointF(lineLength, halfLineWidth);
|
var lp3 = new PointF(lineLength, -halfLineWidth);
|
var lp4 = new PointF(0, -halfLineWidth);
|
var lps = new PointF[] { lp1, lp2, lp3, lp4 };
|
using (var lb = new SolidBrush(lc))
|
{
|
g.FillPolygon(lb, lps);
|
}
|
|
var ap1 = new PointF(lineLength, halfArrowWidth);
|
var ap2 = new PointF(lineLength, -halfArrowWidth);
|
var ap3 = new PointF(lineLength + arrowLength, 0);
|
var aps = new PointF[] { ap1, ap2, ap3 };
|
using (var ab = new SolidBrush(ac))
|
{
|
g.FillPolygon(ab, aps);
|
}
|
|
g.ResetTransform();
|
}
|
|
/// <summary>
|
/// 绘制线
|
/// </summary>
|
/// <param name="g"></param>
|
/// <param name="pf"></param>
|
/// <param name="angle"></param>
|
/// <param name="lineWidth"></param>
|
/// <param name="lineLength"></param>
|
/// <param name="lc"></param>
|
/// <param name="dashStyle"></param>
|
public static void DrawLine(this Graphics g, PointF pf, float angle, float lineWidth, float lineLength, Color lc, DashStyle? dashStyle = null)
|
{
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
g.TranslateTransform(pf.X, pf.Y);
|
g.RotateTransform(angle);
|
using (var pen = new Pen(lc, lineWidth))
|
{
|
if (dashStyle != null)
|
{
|
pen.DashStyle = dashStyle.Value;
|
if (pen.DashStyle == DashStyle.Dash)
|
{
|
pen.DashPattern = new float[] { 10f, 5f };
|
}
|
}
|
g.DrawLine(pen, 0, 0, lineLength, 0);
|
}
|
g.ResetTransform();
|
}
|
|
/// <summary>
|
/// 获取图片物理尺寸(KB)
|
/// </summary>
|
/// <param name="img"></param>
|
public static long GetPhysicalKb(this Image img)
|
{
|
using (var ms = new MemoryStream())
|
{
|
img.Save(ms, ImageFormat.Png);
|
return ms.Length / 1024;
|
}
|
}
|
|
/// <summary>
|
/// 压缩图片
|
/// </summary>
|
/// <param name="img">原图</param>
|
/// <param name="level">压缩等级1-100 越小压缩程度越高</param>
|
/// <param name="size">最终压缩的尺寸</param>
|
public static Image CompressImage(this Image img, int level = 90, int size = 300)
|
{
|
try
|
{
|
var orignSize = img.GetPhysicalKb();
|
if (orignSize <= size)
|
return img.CloneC();
|
if (level < 1)
|
level = 1;
|
if (level > 100)
|
level = 100;
|
ImageFormat tFormat = img.RawFormat;
|
int dHeight = img.Height / 2;
|
int dWidth = img.Width / 2;
|
int sW = 0, sH = 0;
|
//按比例缩放
|
Size tem_size = new Size(img.Width, img.Height);
|
if (tem_size.Width > dHeight || tem_size.Width > dWidth)
|
{
|
if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
|
{
|
sW = dWidth;
|
sH = (dWidth * tem_size.Height) / tem_size.Width;
|
}
|
else
|
{
|
sH = dHeight;
|
sW = (tem_size.Width * dHeight) / tem_size.Height;
|
}
|
}
|
else
|
{
|
sW = tem_size.Width;
|
sH = tem_size.Height;
|
}
|
|
using (var bitmap = new Bitmap(dWidth, dHeight))
|
{
|
using (var g = Graphics.FromImage(bitmap))
|
{
|
g.Clear(Color.WhiteSmoke);
|
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
g.DrawImage(img, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
|
}
|
//以下代码为保存图片时,设置压缩质量
|
EncoderParameters ep = new EncoderParameters();
|
long[] qy = new long[1];
|
qy[0] = level;//设置压缩的比例1-100
|
EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
|
ep.Param[0] = eParam;
|
|
using (var stream = new MemoryStream())
|
{
|
ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
|
ImageCodecInfo jpegICIinfo = null;
|
for (int x = 0; x < arrayICI.Length; x++)
|
{
|
if (arrayICI[x].FormatDescription.Equals("JPEG"))
|
{
|
jpegICIinfo = arrayICI[x];
|
break;
|
}
|
}
|
if (jpegICIinfo != null)
|
{
|
bitmap.Save(stream, jpegICIinfo, ep);
|
}
|
else
|
{
|
bitmap.Save(stream, tFormat);
|
}
|
|
if (stream.Length > 1024 * size)
|
{
|
level -= 10;
|
return CompressImage(bitmap, level, size);
|
}
|
else
|
{
|
return Image.FromStream(stream);
|
}
|
}
|
}
|
}
|
catch (Exception)
|
{
|
return null;
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
}
|