976 lines
42 KiB
C#
976 lines
42 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Drawing;
|
|||
|
|
using System.Drawing.Drawing2D;
|
|||
|
|
using System.Drawing.Imaging;
|
|||
|
|
using System.Drawing.Text;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.Linq;
|
|||
|
|
using System.Net;
|
|||
|
|
using System.Reflection;
|
|||
|
|
using System.Text;
|
|||
|
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TrayNotify;
|
|||
|
|
|
|||
|
|
namespace ryCommon
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 图片相关API
|
|||
|
|
/// </summary>
|
|||
|
|
public static class RyImage
|
|||
|
|
{
|
|||
|
|
#region 内部方法
|
|||
|
|
private static EncoderParameters GetEncoderParameters()
|
|||
|
|
{
|
|||
|
|
System.Drawing.Imaging.Encoder myEncoder;
|
|||
|
|
EncoderParameter myEncoderParameter;
|
|||
|
|
EncoderParameters myEncoderParameters;
|
|||
|
|
|
|||
|
|
myEncoder = System.Drawing.Imaging.Encoder.Quality;
|
|||
|
|
myEncoderParameters = new EncoderParameters(1);
|
|||
|
|
// Save the bitmap as a JPEG file with quality level 100.
|
|||
|
|
myEncoderParameter = new EncoderParameter(myEncoder, 100L);
|
|||
|
|
myEncoderParameters.Param[0] = myEncoderParameter;
|
|||
|
|
return myEncoderParameters;
|
|||
|
|
}
|
|||
|
|
private static ImageCodecInfo GetEncoderInfo(String mimeType)
|
|||
|
|
{
|
|||
|
|
int j;
|
|||
|
|
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
|
|||
|
|
for (j = 0; j < encoders.Length; ++j)
|
|||
|
|
{
|
|||
|
|
if (encoders[j].MimeType == mimeType)
|
|||
|
|
return encoders[j];
|
|||
|
|
}
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
private static ImageCodecInfo GetEncoderInfo(ryCommon.sType.ImageType type)
|
|||
|
|
{
|
|||
|
|
#region 图片格式
|
|||
|
|
ImageCodecInfo myImageCodecInfo;
|
|||
|
|
string type_str = "image/jpeg";
|
|||
|
|
switch (type)
|
|||
|
|
{
|
|||
|
|
case sType.ImageType.Bmp:
|
|||
|
|
type_str = "image/bmp";
|
|||
|
|
break;
|
|||
|
|
case sType.ImageType.Jpeg:
|
|||
|
|
type_str = "image/jpeg";
|
|||
|
|
break;
|
|||
|
|
case sType.ImageType.Gif:
|
|||
|
|
type_str = "image/gif";
|
|||
|
|
break;
|
|||
|
|
case sType.ImageType.Tiff:
|
|||
|
|
type_str = "image/tiff";
|
|||
|
|
break;
|
|||
|
|
case sType.ImageType.Png:
|
|||
|
|
type_str = "image/png";
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
myImageCodecInfo = GetEncoderInfo(type_str);
|
|||
|
|
#endregion
|
|||
|
|
return myImageCodecInfo;
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
/// <summary>
|
|||
|
|
/// 从文件或Url中加载图片,使用本方法,不会导致图片文件被占用。
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="url"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Image LoadPic(string url)
|
|||
|
|
{
|
|||
|
|
if (url.IndexOfEx("http") == 0)
|
|||
|
|
{
|
|||
|
|
Image image = null;
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
WebRequest webreq = WebRequest.Create(url);
|
|||
|
|
WebResponse webres = webreq.GetResponse();
|
|||
|
|
Stream stream = webres.GetResponseStream();
|
|||
|
|
image = Image.FromStream(stream);
|
|||
|
|
stream.Close();
|
|||
|
|
}
|
|||
|
|
catch { }
|
|||
|
|
return image;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (!System.IO.File.Exists(url))
|
|||
|
|
{ return null; }
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
FileStream fs = new FileStream(url, FileMode.Open, FileAccess.Read);
|
|||
|
|
//把文件读取到字节数组
|
|||
|
|
byte[] data = new byte[fs.Length];
|
|||
|
|
fs.Read(data, 0, data.Length);
|
|||
|
|
fs.Close();
|
|||
|
|
|
|||
|
|
//实例化一个内存流--->把从文件流中读取的内容[字节数组]放到内存流中去
|
|||
|
|
MemoryStream ms = new MemoryStream(data);
|
|||
|
|
//设置图片框 pictureBox1中的图片
|
|||
|
|
return Image.FromStream(ms);
|
|||
|
|
}
|
|||
|
|
catch { return null; }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#region SaveHighQualityImage 方法合集
|
|||
|
|
/// <summary>
|
|||
|
|
/// 保存高质量不失真照片
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="m"></param>
|
|||
|
|
/// <param name="path"></param>
|
|||
|
|
/// <param name="type"></param>
|
|||
|
|
public static void SaveHighQualityImage(this Bitmap m, string path, ryCommon.sType.ImageType type)
|
|||
|
|
{
|
|||
|
|
m.Save(path, GetEncoderInfo(type), GetEncoderParameters());
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 保存高质量不失真照片
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="m"></param>
|
|||
|
|
/// <param name="ms"></param>
|
|||
|
|
/// <param name="type"></param>
|
|||
|
|
public static void SaveHighQualityImage(this Bitmap m, MemoryStream ms, ryCommon.sType.ImageType type)
|
|||
|
|
{
|
|||
|
|
m.Save(ms, GetEncoderInfo(type), GetEncoderParameters());
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 保存高质量不失真照片
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="m"></param>
|
|||
|
|
/// <param name="path"></param>
|
|||
|
|
/// <param name="type"></param>
|
|||
|
|
public static void SaveHighQualityImage(this Image m, string path, ryCommon.sType.ImageType type)
|
|||
|
|
{
|
|||
|
|
m.Save(path, GetEncoderInfo(type), GetEncoderParameters());
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 保存高质量不失真照片
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="m"></param>
|
|||
|
|
/// <param name="path"></param>
|
|||
|
|
public static bool SaveHighQualityImage(this Bitmap m, string path)
|
|||
|
|
{
|
|||
|
|
return SaveHighQualityImage((Image)m, path);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 保存高质量不失真照片
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="m"></param>
|
|||
|
|
/// <param name="path"></param>
|
|||
|
|
public static bool SaveHighQualityImage(this Image m, string path)
|
|||
|
|
{
|
|||
|
|
ryCommon.sType.ImageType type = sType.ImageType.Png;
|
|||
|
|
var ext = System.IO.Path.GetExtension(path).ToLower();
|
|||
|
|
switch (ext)
|
|||
|
|
{
|
|||
|
|
case ".png":
|
|||
|
|
m.Save(path, GetEncoderInfo(type), GetEncoderParameters());
|
|||
|
|
break;
|
|||
|
|
case ".jpg":
|
|||
|
|
type = sType.ImageType.Jpeg;
|
|||
|
|
m.Save(path, GetEncoderInfo(type), GetEncoderParameters());
|
|||
|
|
break;
|
|||
|
|
case ".bmp":
|
|||
|
|
type = sType.ImageType.Bmp;
|
|||
|
|
m.Save(path, GetEncoderInfo(type), GetEncoderParameters());
|
|||
|
|
break;
|
|||
|
|
case ".gif":
|
|||
|
|
type = sType.ImageType.Gif;
|
|||
|
|
m.Save(path, GetEncoderInfo(type), GetEncoderParameters());
|
|||
|
|
break;
|
|||
|
|
case ".tif":
|
|||
|
|
type = sType.ImageType.Tiff;
|
|||
|
|
m.Save(path, GetEncoderInfo(type), GetEncoderParameters());
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
#region 图片旋转函数
|
|||
|
|
/// <summary>
|
|||
|
|
/// 以逆时针为方向对图像进行旋转
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="b">位图流</param>
|
|||
|
|
/// <param name="angle">旋转角度[0,360](前台给的)</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap Rotate(this Bitmap b, int angle)
|
|||
|
|
{
|
|||
|
|
angle = angle % 360;
|
|||
|
|
//弧度转换
|
|||
|
|
double radian = angle * Math.PI / 180.0;
|
|||
|
|
double cos = Math.Cos(radian);
|
|||
|
|
double sin = Math.Sin(radian);
|
|||
|
|
//原图的宽和高
|
|||
|
|
int w = b.Width;
|
|||
|
|
int h = b.Height;
|
|||
|
|
int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin)));
|
|||
|
|
int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos)));
|
|||
|
|
//目标位图
|
|||
|
|
Bitmap dsImage = new Bitmap(W, H);
|
|||
|
|
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(dsImage);
|
|||
|
|
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;
|
|||
|
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
|||
|
|
//计算偏移量
|
|||
|
|
Point Offset = new Point((W - w) / 2, (H - h) / 2);
|
|||
|
|
//构造图像显示区域:让图像的中心与窗口的中心点一致
|
|||
|
|
Rectangle rect = new Rectangle(Offset.X, Offset.Y, w, h);
|
|||
|
|
Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
|
|||
|
|
g.TranslateTransform(center.X, center.Y);
|
|||
|
|
g.RotateTransform(360 - angle);
|
|||
|
|
//恢复图像在水平和垂直方向的平移
|
|||
|
|
g.TranslateTransform(-center.X, -center.Y);
|
|||
|
|
g.DrawImage(b, rect);
|
|||
|
|
//重至绘图的所有变换
|
|||
|
|
g.ResetTransform();
|
|||
|
|
g.Save();
|
|||
|
|
g.Dispose();
|
|||
|
|
//dsImage.Save("yuancd.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
|
|||
|
|
return dsImage;
|
|||
|
|
}
|
|||
|
|
#endregion 图片旋转函数
|
|||
|
|
/// <summary>
|
|||
|
|
/// 是否包括透明像素
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
/// <exception cref="Exception">操作失败</exception>
|
|||
|
|
public static bool HasTransparentPixel(this System.Drawing.Image i)
|
|||
|
|
{
|
|||
|
|
using (Bitmap bitmap = new Bitmap(i))
|
|||
|
|
{
|
|||
|
|
for (int x = 0; x < bitmap.Width; x++)
|
|||
|
|
{
|
|||
|
|
for (int y = 0; y < bitmap.Height; y++)
|
|||
|
|
{
|
|||
|
|
if (bitmap.GetPixel(x, y).A < 255)
|
|||
|
|
{
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 矩形边界
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="bounds"></param>
|
|||
|
|
/// <param name="rect"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private static Size ScaleRectangleToFitBounds(Size bounds, Size rect)
|
|||
|
|
{
|
|||
|
|
if (rect.Width < bounds.Width && rect.Height < bounds.Height)
|
|||
|
|
{
|
|||
|
|
return rect;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (bounds.Width == 0 || bounds.Height == 0)
|
|||
|
|
{
|
|||
|
|
return new Size(0, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
double scaleFactorWidth = (double)rect.Width / bounds.Width;
|
|||
|
|
double scaleFactorHeight = (double)rect.Height / bounds.Height;
|
|||
|
|
|
|||
|
|
double scaleFactor = Math.Max(scaleFactorWidth, scaleFactorHeight);
|
|||
|
|
return new Size()
|
|||
|
|
{
|
|||
|
|
Width = (int)(rect.Width / scaleFactor),
|
|||
|
|
Height = (int)(rect.Height / scaleFactor)
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 计算水印位置
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="watermarkPosition"></param>
|
|||
|
|
/// <param name="imageSize"></param>
|
|||
|
|
/// <param name="watermarkSize"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private static Point CalculateWatermarkPosition(WatermarkPosition watermarkPosition, Size imageSize, Size watermarkSize)
|
|||
|
|
{
|
|||
|
|
Point position = new Point();
|
|||
|
|
switch (watermarkPosition)
|
|||
|
|
{
|
|||
|
|
case WatermarkPosition.TopLeftCorner:
|
|||
|
|
position.X = 0;
|
|||
|
|
position.Y = 0;
|
|||
|
|
break;
|
|||
|
|
case WatermarkPosition.TopCenter:
|
|||
|
|
position.X = (imageSize.Width / 2) - (watermarkSize.Width / 2);
|
|||
|
|
position.Y = 0;
|
|||
|
|
break;
|
|||
|
|
case WatermarkPosition.TopRightCorner:
|
|||
|
|
position.X = imageSize.Width - watermarkSize.Width;
|
|||
|
|
position.Y = 0;
|
|||
|
|
break;
|
|||
|
|
case WatermarkPosition.CenterLeft:
|
|||
|
|
position.X = 0;
|
|||
|
|
position.Y = (imageSize.Height / 2) - (watermarkSize.Height / 2);
|
|||
|
|
break;
|
|||
|
|
case WatermarkPosition.Center:
|
|||
|
|
position.X = (imageSize.Width / 2) - (watermarkSize.Width / 2);
|
|||
|
|
position.Y = (imageSize.Height / 2) - (watermarkSize.Height / 2);
|
|||
|
|
break;
|
|||
|
|
case WatermarkPosition.CenterRight:
|
|||
|
|
position.X = imageSize.Width - watermarkSize.Width;
|
|||
|
|
position.Y = (imageSize.Height / 2) - (watermarkSize.Height / 2);
|
|||
|
|
break;
|
|||
|
|
case WatermarkPosition.BottomLeftCorner:
|
|||
|
|
position.X = 0;
|
|||
|
|
position.Y = imageSize.Height - watermarkSize.Height;
|
|||
|
|
break;
|
|||
|
|
case WatermarkPosition.BottomCenter:
|
|||
|
|
position.X = (imageSize.Width / 2) - (watermarkSize.Width / 2);
|
|||
|
|
position.Y = imageSize.Height - watermarkSize.Height;
|
|||
|
|
break;
|
|||
|
|
case WatermarkPosition.BottomRightCorner:
|
|||
|
|
position.X = imageSize.Width - watermarkSize.Width;
|
|||
|
|
position.Y = imageSize.Height - watermarkSize.Height;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return position;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 写入水印
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">原图</param>
|
|||
|
|
/// <param name="wmImg">水印图片</param>
|
|||
|
|
/// <param name="Position">水印位置</param>
|
|||
|
|
/// <param name="opacity">不透明度(0~1),越小越透明</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap DrawWatermark(this Image image, Bitmap wmImg, WatermarkPosition Position, float opacity)
|
|||
|
|
{
|
|||
|
|
return DrawWatermark(image, wmImg, new List<WatermarkPosition>() { Position }, 0,0, opacity);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 写入水印
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">原图</param>
|
|||
|
|
/// <param name="wmImg">水印图片</param>
|
|||
|
|
/// <param name="Position">水印位置</param>
|
|||
|
|
/// <param name="offset_x">x坐标偏移</param>
|
|||
|
|
/// <param name="offset_y">y坐标偏移</param>
|
|||
|
|
/// <param name="opacity">不透明度(0~1),越小越透明</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap DrawWatermark(this Image image, Bitmap wmImg, WatermarkPosition Position, int offset_x, int offset_y, float opacity)
|
|||
|
|
{
|
|||
|
|
return DrawWatermark(image, wmImg, new List<WatermarkPosition>() { Position }, offset_x, offset_y, opacity);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 写入水印
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">原图</param>
|
|||
|
|
/// <param name="wmImg">水印图片</param>
|
|||
|
|
/// <param name="PositionList">水印位置</param>
|
|||
|
|
/// <param name="offset_x">x坐标偏移</param>
|
|||
|
|
/// <param name="offset_y">y坐标偏移</param>
|
|||
|
|
/// <param name="opacity">不透明度(0~1),越小越透明</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap DrawWatermark(this Image image, Bitmap wmImg, List<WatermarkPosition> PositionList,int offset_x, int offset_y, float opacity)
|
|||
|
|
{
|
|||
|
|
Bitmap bm1 = new Bitmap(image); //克隆原图,它也是我们的返回值
|
|||
|
|
using (Graphics g = Graphics.FromImage(bm1))
|
|||
|
|
{
|
|||
|
|
Size calculatedWatermarkSize = ScaleRectangleToFitBounds(bm1.Size, wmImg.Size);
|
|||
|
|
|
|||
|
|
if (calculatedWatermarkSize.Width == 0 || calculatedWatermarkSize.Height == 0)
|
|||
|
|
{
|
|||
|
|
return bm1;
|
|||
|
|
}
|
|||
|
|
Bitmap scaledWatermarkBitmap =
|
|||
|
|
new Bitmap(calculatedWatermarkSize.Width, calculatedWatermarkSize.Height);
|
|||
|
|
using (Graphics watermarkGraphics = Graphics.FromImage(scaledWatermarkBitmap))
|
|||
|
|
{
|
|||
|
|
ColorMatrix opacityMatrix = new ColorMatrix
|
|||
|
|
{
|
|||
|
|
Matrix33 = opacity
|
|||
|
|
};
|
|||
|
|
ImageAttributes attrs = new ImageAttributes();
|
|||
|
|
attrs.SetColorMatrix(opacityMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
|
|||
|
|
watermarkGraphics.DrawImage(wmImg,
|
|||
|
|
new Rectangle(0, 0, scaledWatermarkBitmap.Width, scaledWatermarkBitmap.Height),
|
|||
|
|
0, 0, wmImg.Width, wmImg.Height,
|
|||
|
|
GraphicsUnit.Pixel, attrs);
|
|||
|
|
attrs.Dispose();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
foreach (var position in PositionList)
|
|||
|
|
{
|
|||
|
|
if(position== WatermarkPosition.FullScreenTile)
|
|||
|
|
{
|
|||
|
|
//g.RotateTransform(-45);
|
|||
|
|
//scaledWatermarkBitmap=scaledWatermarkBitmap.Rotate(45);
|
|||
|
|
var space = 100;
|
|||
|
|
var start_y = ((scaledWatermarkBitmap.Width - scaledWatermarkBitmap.Height) / Math.Sqrt(2)) + (Math.Sqrt(2) * scaledWatermarkBitmap.Height)- scaledWatermarkBitmap.Size.Height;
|
|||
|
|
for (int i_y = start_y.ToInt()-50+offset_y; i_y < image.Size.Height*2; i_y += scaledWatermarkBitmap.Height + space)
|
|||
|
|
{
|
|||
|
|
for (int i_x = offset_x; i_x < image.Size.Width; i_x += scaledWatermarkBitmap.Width + space)
|
|||
|
|
{
|
|||
|
|
var bottomleft_x = i_x;
|
|||
|
|
var bottomleft_y = i_y+ scaledWatermarkBitmap.Size.Height;
|
|||
|
|
var bottomright_x = i_x +(scaledWatermarkBitmap.Size.Width / Math.Sqrt(2));//水印右上角x坐标
|
|||
|
|
var bottomright_y = bottomleft_y - (scaledWatermarkBitmap.Size.Width / Math.Sqrt(2));//水印右上角y坐标
|
|||
|
|
if (bottomright_x> image.Size.Width){ continue; }
|
|||
|
|
if (bottomright_y< 0){ continue; }
|
|||
|
|
if(bottomright_y > image.Size.Height) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
if (bottomleft_y > image.Size.Height) {
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
//if ((xx* Math.Sqrt(2))< scaledWatermarkBitmap.Size.Width) { continue; }
|
|||
|
|
g.TranslateTransform(bottomleft_x, bottomleft_y);
|
|||
|
|
g.RotateTransform(-45);
|
|||
|
|
//if (i_x+ scaledWatermarkBitmap.Width> image.Size.Width) { continue; }
|
|||
|
|
//if (i_y + scaledWatermarkBitmap.Height > image.Size.Height) { continue; }
|
|||
|
|
g.DrawImage(scaledWatermarkBitmap,
|
|||
|
|
new Rectangle(new Point(0,0), scaledWatermarkBitmap.Size),
|
|||
|
|
0, 0, scaledWatermarkBitmap.Width, scaledWatermarkBitmap.Height, GraphicsUnit.Pixel);
|
|||
|
|
g.TranslateTransform(-bottomleft_x, -bottomleft_y);
|
|||
|
|
g.RotateTransform(45);
|
|||
|
|
///////重置绘图平面的所有变换
|
|||
|
|
g.ResetTransform();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
Point watermarkPosition = CalculateWatermarkPosition(position,
|
|||
|
|
image.Size, calculatedWatermarkSize);
|
|||
|
|
watermarkPosition.Offset(offset_x, offset_y);
|
|||
|
|
if(watermarkPosition.X<0 || watermarkPosition.Y < 0) { continue; }
|
|||
|
|
if (watermarkPosition.X > bm1.Width- calculatedWatermarkSize.Width || watermarkPosition.Y>bm1.Height- calculatedWatermarkSize.Height) { continue; }
|
|||
|
|
g.DrawImage(scaledWatermarkBitmap,
|
|||
|
|
new Rectangle(watermarkPosition, calculatedWatermarkSize),
|
|||
|
|
0, 0, calculatedWatermarkSize.Width, calculatedWatermarkSize.Height, GraphicsUnit.Pixel);
|
|||
|
|
}
|
|||
|
|
scaledWatermarkBitmap.Dispose();
|
|||
|
|
}
|
|||
|
|
return bm1;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 计算最大字体大小
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="text"></param>
|
|||
|
|
/// <param name="angle"></param>
|
|||
|
|
/// <param name="fontName"></param>
|
|||
|
|
/// <param name="maxTextSize"></param>
|
|||
|
|
/// <param name="g"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private static int ComputeMaxFontSize(string text, int angle, string fontName, Size maxTextSize, Graphics g)
|
|||
|
|
{
|
|||
|
|
for (int fontSize = 2; ; fontSize++)
|
|||
|
|
{
|
|||
|
|
using (Font tmpFont = new Font(fontName, fontSize, FontStyle.Bold))
|
|||
|
|
{
|
|||
|
|
SizeF textSize = g.MeasureString(text, tmpFont);
|
|||
|
|
SizeF rotatedTextSize = CalculateRotatedRectSize(textSize, angle);
|
|||
|
|
if (((int)rotatedTextSize.Width > maxTextSize.Width) ||
|
|||
|
|
((int)rotatedTextSize.Height > maxTextSize.Height))
|
|||
|
|
{
|
|||
|
|
return fontSize - 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 计算旋转矩形大小
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="rectSize"></param>
|
|||
|
|
/// <param name="angleDeg"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private static SizeF CalculateRotatedRectSize(SizeF rectSize, double angleDeg)
|
|||
|
|
{
|
|||
|
|
double angleRad = angleDeg * Math.PI / 180;
|
|||
|
|
double width = rectSize.Height * Math.Abs(Math.Sin(angleRad)) +
|
|||
|
|
rectSize.Width * Math.Abs(Math.Cos(angleRad));
|
|||
|
|
double height = rectSize.Height * Math.Abs(Math.Cos(angleRad)) +
|
|||
|
|
rectSize.Width * Math.Abs(Math.Sin(angleRad));
|
|||
|
|
return new SizeF((float)width, (float)height);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 写入水印文字
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">图片</param>
|
|||
|
|
/// <param name="wmText">水印文字</param>
|
|||
|
|
/// <param name="WatermarkFont">水印字体名字</param>
|
|||
|
|
/// <param name="TextColor">字体颜色</param>
|
|||
|
|
/// <param name="TextSize">字体大小</param>
|
|||
|
|
/// <param name="TextRotatedDegree">旋转角度</param>
|
|||
|
|
/// <param name="PositionList">水印位置</param>
|
|||
|
|
/// <param name="x">x坐标偏移</param>
|
|||
|
|
/// <param name="y">y坐标偏移</param>
|
|||
|
|
/// <param name="opacity">不透明度(0~1),越小越透明</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap DrawWatermark(this Image image, string wmText,string WatermarkFont,Color TextColor, int TextSize, int TextRotatedDegree, List<WatermarkPosition> PositionList, int x, int y, float opacity)
|
|||
|
|
{
|
|||
|
|
Bitmap bm1 = new Bitmap(image); //克隆原图,它也是我们的返回值
|
|||
|
|
using (Graphics g = Graphics.FromImage(bm1))
|
|||
|
|
{
|
|||
|
|
g.SmoothingMode = SmoothingMode.AntiAlias;
|
|||
|
|
g.TextRenderingHint = TextRenderingHint.AntiAlias;
|
|||
|
|
|
|||
|
|
string text = wmText;
|
|||
|
|
|
|||
|
|
int textAngle = TextRotatedDegree;
|
|||
|
|
double sizeFactor = (double)TextSize / 100;
|
|||
|
|
Size maxTextSize = new Size(
|
|||
|
|
(int)(bm1.Width * sizeFactor),
|
|||
|
|
(int)(bm1.Height * sizeFactor));
|
|||
|
|
|
|||
|
|
int fontSize = ComputeMaxFontSize(text, textAngle, WatermarkFont, maxTextSize, g);
|
|||
|
|
|
|||
|
|
Font font = new Font(WatermarkFont, (float)fontSize, FontStyle.Bold);
|
|||
|
|
SizeF originalTextSize = g.MeasureString(text, font);
|
|||
|
|
SizeF rotatedTextSize = CalculateRotatedRectSize(originalTextSize, textAngle);
|
|||
|
|
|
|||
|
|
Bitmap textBitmap = new Bitmap((int)rotatedTextSize.Width, (int)rotatedTextSize.Height,
|
|||
|
|
PixelFormat.Format32bppArgb);
|
|||
|
|
using (Graphics textG = Graphics.FromImage(textBitmap))
|
|||
|
|
{
|
|||
|
|
Color color = Color.FromArgb((int)(opacity * 255), TextColor);
|
|||
|
|
SolidBrush brush = new SolidBrush(color);
|
|||
|
|
|
|||
|
|
textG.TranslateTransform(rotatedTextSize.Width / 2, rotatedTextSize.Height / 2);
|
|||
|
|
textG.RotateTransform((float)textAngle);
|
|||
|
|
textG.DrawString(text, font, brush, -originalTextSize.Width / 2,
|
|||
|
|
-originalTextSize.Height / 2);
|
|||
|
|
textG.ResetTransform();
|
|||
|
|
|
|||
|
|
brush.Dispose();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
foreach (var position in PositionList)
|
|||
|
|
{
|
|||
|
|
Point textPosition = CalculateWatermarkPosition(position,
|
|||
|
|
bm1.Size, rotatedTextSize.ToSize());
|
|||
|
|
g.DrawImage(textBitmap, textPosition);
|
|||
|
|
}
|
|||
|
|
textBitmap.Dispose();
|
|||
|
|
font.Dispose();
|
|||
|
|
}
|
|||
|
|
return bm1;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 写入水印文字
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">图片</param>
|
|||
|
|
/// <param name="wmText">水印文字</param>
|
|||
|
|
/// <param name="WatermarkFont">水印字体名字</param>
|
|||
|
|
/// <param name="TextColor">字体颜色</param>
|
|||
|
|
/// <param name="TextSize">字体大小</param>
|
|||
|
|
/// <param name="TextRotatedDegree">旋转角度</param>
|
|||
|
|
/// <param name="Position">水印位置</param>
|
|||
|
|
/// <param name="x">x坐标偏移</param>
|
|||
|
|
/// <param name="y">y坐标偏移</param>
|
|||
|
|
/// <param name="opacity">不透明度(0~1),越小越透明</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap DrawWatermark(this Image image, string wmText, string WatermarkFont, Color TextColor, int TextSize, int TextRotatedDegree, WatermarkPosition Position, int x, int y, float opacity)
|
|||
|
|
{
|
|||
|
|
return DrawWatermark(image, wmText, WatermarkFont, TextColor, TextSize, TextRotatedDegree,
|
|||
|
|
new List<WatermarkPosition>() { Position }, x, y, opacity);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 写入水印文字
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">图片</param>
|
|||
|
|
/// <param name="wmText">水印文字</param>
|
|||
|
|
/// <param name="WatermarkFont">水印字体名字</param>
|
|||
|
|
/// <param name="TextColor">字体颜色</param>
|
|||
|
|
/// <param name="TextSize">字体大小</param>
|
|||
|
|
/// <param name="TextRotatedDegree">旋转角度</param>
|
|||
|
|
/// <param name="Position">水印位置</param>
|
|||
|
|
/// <param name="opacity">不透明度(0~1),越小越透明</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap DrawWatermark(this Image image, string wmText, string WatermarkFont, Color TextColor, int TextSize, int TextRotatedDegree, WatermarkPosition Position, float opacity)
|
|||
|
|
{
|
|||
|
|
return DrawWatermark(image, wmText, WatermarkFont, TextColor, TextSize, TextRotatedDegree,
|
|||
|
|
new List<WatermarkPosition>() { Position }, 0,0, opacity);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 往图片右下角写入水印文字
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">图片</param>
|
|||
|
|
/// <param name="wmText">水印文字</param>
|
|||
|
|
/// <param name="WatermarkFont">水印字体名字</param>
|
|||
|
|
/// <param name="TextColor">字体颜色</param>
|
|||
|
|
/// <param name="TextSize">字体大小</param>
|
|||
|
|
/// <param name="opacity">不透明度(0~1),越小越透明</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap DrawWatermark(this Image image, string wmText, string WatermarkFont, Color TextColor, int TextSize, float opacity)
|
|||
|
|
{
|
|||
|
|
return DrawWatermark(image, wmText, WatermarkFont, TextColor, TextSize, 0,
|
|||
|
|
new List<WatermarkPosition>() { WatermarkPosition.BottomRightCorner }, 0, 0, opacity);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 往图片右下角写入水印文字
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">图片</param>
|
|||
|
|
/// <param name="wmText">水印文字</param>
|
|||
|
|
/// <param name="WatermarkFont">水印字体名字</param>
|
|||
|
|
/// <param name="TextColor">字体颜色</param>
|
|||
|
|
/// <param name="TextSize">字体大小</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Bitmap DrawWatermark(this Image image, string wmText, string WatermarkFont, Color TextColor, int TextSize)
|
|||
|
|
{
|
|||
|
|
return DrawWatermark(image, wmText, WatermarkFont, TextColor, TextSize, 0,
|
|||
|
|
new List<WatermarkPosition>() { WatermarkPosition.BottomRightCorner }, 0, 0, 0.1f);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 缩放
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="width">宽</param>
|
|||
|
|
/// <param name="height">高</param>
|
|||
|
|
/// <param name="mode">插值算法</param>
|
|||
|
|
/// <returns>返回缩放后的图片</returns>
|
|||
|
|
/// <exception cref="NullReferenceException">Image 不能为 null</exception>
|
|||
|
|
/// <exception cref="Exception">操作失败</exception>
|
|||
|
|
public static System.Drawing.Image Zoom(this System.Drawing.Image i, int width, int height, InterpolationMode mode)
|
|||
|
|
{
|
|||
|
|
Bitmap bitmap = new Bitmap(width, height);
|
|||
|
|
using (Graphics g = Graphics.FromImage(bitmap))
|
|||
|
|
{
|
|||
|
|
g.InterpolationMode = mode;
|
|||
|
|
g.Clear(Color.Empty);
|
|||
|
|
g.DrawImage(i, new Rectangle(0, 0, width, height), new Rectangle(0, 0, i.Width, i.Height), GraphicsUnit.Pixel);
|
|||
|
|
}
|
|||
|
|
return bitmap;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 缩放
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="width">宽</param>
|
|||
|
|
/// <param name="height">高</param>
|
|||
|
|
/// <returns>返回缩放后的图片</returns>
|
|||
|
|
/// <exception cref="NullReferenceException">Image 不能为 null</exception>
|
|||
|
|
/// <exception cref="Exception">操作失败</exception>
|
|||
|
|
public static System.Drawing.Image Zoom(this System.Drawing.Image i, int width, int height)
|
|||
|
|
{
|
|||
|
|
Bitmap bitmap = new Bitmap(width, height);
|
|||
|
|
using (Graphics g = Graphics.FromImage(bitmap))
|
|||
|
|
{
|
|||
|
|
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|||
|
|
g.Clear(Color.Empty);
|
|||
|
|
g.DrawImage(i, new Rectangle(0, 0, width, height), new Rectangle(0, 0, i.Width, i.Height), GraphicsUnit.Pixel);
|
|||
|
|
}
|
|||
|
|
return bitmap;
|
|||
|
|
}
|
|||
|
|
#endregion
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据原边长和新边长计算绘制的起始点坐标
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="oldLength"></param>
|
|||
|
|
/// <param name="newLength"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private static int GetSrc(int oldLength, int newLength)
|
|||
|
|
{
|
|||
|
|
return ((float)(oldLength - newLength) / 2).ToInt();
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 获取缩放模式
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="oldWidth"></param>
|
|||
|
|
/// <param name="oldHeight"></param>
|
|||
|
|
/// <param name="newWidth"></param>
|
|||
|
|
/// <param name="newHeight"></param>
|
|||
|
|
/// <param name="crop">是否裁剪图片</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
private static ResizeMode GetMode(int oldWidth, int oldHeight, int newWidth, int newHeight, bool crop)
|
|||
|
|
{
|
|||
|
|
float oldScale = (float)oldWidth / oldHeight;
|
|||
|
|
float newScale = (float)newWidth / newHeight;
|
|||
|
|
if (crop)
|
|||
|
|
{
|
|||
|
|
return oldScale < newScale ? ResizeMode.WidthFirst : ResizeMode.HeightFirst;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return oldScale > newScale ? ResizeMode.WidthFirst : ResizeMode.HeightFirst;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 裁剪或填充
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image"></param>
|
|||
|
|
/// <param name="width"></param>
|
|||
|
|
/// <param name="height"></param>
|
|||
|
|
/// <param name="background">背景色</param>
|
|||
|
|
/// <param name="mode">插值算法</param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
/// <exception cref="NullReferenceException">Image 不能为 null</exception>
|
|||
|
|
/// <exception cref="Exception">操作失败</exception>
|
|||
|
|
private static System.Drawing.Image CropOrFill(this System.Drawing.Image image, int width, int height, Color background, InterpolationMode mode)
|
|||
|
|
{
|
|||
|
|
Bitmap bitmap = new Bitmap(width, height);
|
|||
|
|
using (Graphics g = Graphics.FromImage(bitmap))
|
|||
|
|
{
|
|||
|
|
g.InterpolationMode = mode;
|
|||
|
|
int srcX = GetSrc(image.Width, width);
|
|||
|
|
int srcY = GetSrc(image.Height, height);
|
|||
|
|
g.Clear(background);
|
|||
|
|
g.DrawImage(image, new Rectangle(0, 0, width, height), srcX, srcY, width, height, GraphicsUnit.Pixel);
|
|||
|
|
}
|
|||
|
|
return bitmap;
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 裁剪
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="width">宽度</param>
|
|||
|
|
/// <param name="height">高度</param>
|
|||
|
|
/// <param name="interpolationMode"></param>
|
|||
|
|
/// <returns>返回裁剪后的图片</returns>
|
|||
|
|
/// <exception cref="NullReferenceException">Image 不能为 null</exception>
|
|||
|
|
/// <exception cref="ArgumentOutOfRangeException">新的图片尺寸的宽度和高度必须大于零</exception>
|
|||
|
|
/// <exception cref="Exception">操作失败</exception>
|
|||
|
|
public static System.Drawing.Image Crop(this System.Drawing.Image i, int width, int height, InterpolationMode interpolationMode)
|
|||
|
|
{
|
|||
|
|
return i.ReSize(width, height,Color.Transparent, GetMode(i.Width, i.Height, width, height, true), interpolationMode);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 调整宽度
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="width"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Image ReSizeW(this Image i, int width)
|
|||
|
|
{
|
|||
|
|
return i.ReSize(width, (((float)width / i.Width) * i.Height).ToInt(), ResizeMode.WidthFirst);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据最大宽度调整图片尺寸
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="maxWidth">最大宽度</param>
|
|||
|
|
/// <returns>返回调整后的图片</returns>
|
|||
|
|
/// <exception cref="NullReferenceException">Image 不能为 null</exception>
|
|||
|
|
/// <exception cref="ArgumentOutOfRangeException">最大宽度必须大于零</exception>
|
|||
|
|
/// <exception cref="Exception">操作失败</exception>
|
|||
|
|
public static System.Drawing.Image ResizeMaxW(this System.Drawing.Image i, int maxWidth)
|
|||
|
|
{
|
|||
|
|
if (i.Width > maxWidth)
|
|||
|
|
{
|
|||
|
|
return i.ReSizeW(maxWidth);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return (System.Drawing.Image)i.Clone();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据最大高度调整图片尺寸
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="maxHeight">最大高度</param>
|
|||
|
|
/// <returns>返回调整后的图片</returns>
|
|||
|
|
/// <exception cref="NullReferenceException">Image 不能为 null</exception>
|
|||
|
|
/// <exception cref="ArgumentOutOfRangeException">最大宽度必须大于零</exception>
|
|||
|
|
/// <exception cref="Exception">操作失败</exception>
|
|||
|
|
public static System.Drawing.Image ResizeMaxH(this System.Drawing.Image i, int maxHeight)
|
|||
|
|
{
|
|||
|
|
if (i.Height > maxHeight)
|
|||
|
|
{
|
|||
|
|
return i.ReSizeH(maxHeight);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
return (System.Drawing.Image)i.Clone();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 调整高度
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="height"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Image ReSizeH(this Image i, int height)
|
|||
|
|
{
|
|||
|
|
return i.ReSize((((float)height / i.Height) * i.Width).ToInt(), height, ResizeMode.WidthFirst);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 调整图片大小
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="width"></param>
|
|||
|
|
/// <param name="height"></param>
|
|||
|
|
/// <param name="resizeMode"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Image ReSize(this Image i, int width, int height, ResizeMode resizeMode)
|
|||
|
|
{
|
|||
|
|
return ReSize(i, width, height, Color.Transparent, resizeMode);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 调整图片大小
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="width"></param>
|
|||
|
|
/// <param name="height"></param>
|
|||
|
|
/// <param name="background"></param>
|
|||
|
|
/// <param name="resizeMode"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
public static Image ReSize(this Image i, int width, int height, Color background, ResizeMode resizeMode)
|
|||
|
|
{
|
|||
|
|
return ReSize(i,width,height,background,resizeMode, InterpolationMode.HighQualityBilinear);
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 调整图片大小
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="i"></param>
|
|||
|
|
/// <param name="width"></param>
|
|||
|
|
/// <param name="height"></param>
|
|||
|
|
/// <param name="background"></param>
|
|||
|
|
/// <param name="resizeMode"></param>
|
|||
|
|
/// <param name="interpolationMode"></param>
|
|||
|
|
/// <returns></returns>
|
|||
|
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
|||
|
|
public static Image ReSize(this Image i,int width,int height, Color background, ResizeMode resizeMode, InterpolationMode interpolationMode)
|
|||
|
|
{
|
|||
|
|
if (width <= 0 || height <= 0)
|
|||
|
|
{
|
|||
|
|
throw new ArgumentOutOfRangeException("新的图片尺寸的宽和高必须大于零");
|
|||
|
|
}
|
|||
|
|
//如果原图片和新图片尺寸一致,克隆对象返回
|
|||
|
|
if (i.Width == width && i.Height == height)
|
|||
|
|
{
|
|||
|
|
return (System.Drawing.Image)i.Clone();
|
|||
|
|
}
|
|||
|
|
if (((float)i.Width / i.Height == (float)width / height))
|
|||
|
|
{
|
|||
|
|
//如果原图片和新图片的比例相同,只缩放
|
|||
|
|
return i.Zoom(width, height);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
Size size = new Size();
|
|||
|
|
//新宽高比
|
|||
|
|
float scale = (float)width / height;
|
|||
|
|
if (resizeMode == ResizeMode.WidthFirst)
|
|||
|
|
{
|
|||
|
|
//等宽,计算高
|
|||
|
|
size.Width = i.Width;
|
|||
|
|
size.Height = (i.Width / scale).ToInt();
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
//等高,计算宽
|
|||
|
|
size.Height = i.Height;
|
|||
|
|
size.Width = (i.Height * scale).ToInt();
|
|||
|
|
}
|
|||
|
|
//如果原图片和新图片的比例不同,先裁剪或填充后,再缩放
|
|||
|
|
using (System.Drawing.Image cropOrFill = i.CropOrFill(size.Width, size.Height, background, interpolationMode))
|
|||
|
|
{
|
|||
|
|
return cropOrFill.Zoom(width, height, interpolationMode);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 转换Image为Icon
|
|||
|
|
/// </summary>
|
|||
|
|
/// <param name="image">要转换为图标的Image对象</param>
|
|||
|
|
/// <param name="nullTonull">当image为null时是否返回null。false则抛空引用异常</param>
|
|||
|
|
/// <exception cref="ArgumentNullException" />
|
|||
|
|
public static Icon ConvertToIcon(Image image, bool nullTonull = false)
|
|||
|
|
{
|
|||
|
|
if (image == null)
|
|||
|
|
{
|
|||
|
|
if (nullTonull) { return null; }
|
|||
|
|
throw new ArgumentNullException("image");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
using (MemoryStream msImg = new MemoryStream()
|
|||
|
|
, msIco = new MemoryStream())
|
|||
|
|
{
|
|||
|
|
image.Save(msImg, ImageFormat.Png);
|
|||
|
|
|
|||
|
|
using (var bin = new BinaryWriter(msIco))
|
|||
|
|
{
|
|||
|
|
//写图标头部
|
|||
|
|
bin.Write((short)0); //0-1保留
|
|||
|
|
bin.Write((short)1); //2-3文件类型。1=图标, 2=光标
|
|||
|
|
bin.Write((short)1); //4-5图像数量(图标可以包含多个图像)
|
|||
|
|
|
|||
|
|
bin.Write((byte)image.Width); //6图标宽度
|
|||
|
|
bin.Write((byte)image.Height); //7图标高度
|
|||
|
|
bin.Write((byte)0); //8颜色数(若像素位深>=8,填0。这是显然的,达到8bpp的颜色数最少是256,byte不够表示)
|
|||
|
|
bin.Write((byte)0); //9保留。必须为0
|
|||
|
|
bin.Write((short)0); //10-11调色板
|
|||
|
|
bin.Write((short)32); //12-13位深
|
|||
|
|
bin.Write((int)msImg.Length); //14-17位图数据大小
|
|||
|
|
bin.Write(22); //18-21位图数据起始字节
|
|||
|
|
|
|||
|
|
//写图像数据
|
|||
|
|
bin.Write(msImg.ToArray());
|
|||
|
|
|
|||
|
|
bin.Flush();
|
|||
|
|
bin.Seek(0, SeekOrigin.Begin);
|
|||
|
|
return new Icon(msIco);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 缩放模式
|
|||
|
|
/// </summary>
|
|||
|
|
public enum ResizeMode
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 宽度优先(不裁剪宽)
|
|||
|
|
/// </summary>
|
|||
|
|
WidthFirst,
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 高度优先(不裁剪高)
|
|||
|
|
/// </summary>
|
|||
|
|
HeightFirst
|
|||
|
|
}
|
|||
|
|
/// <summary>
|
|||
|
|
/// 水印位置
|
|||
|
|
/// </summary>
|
|||
|
|
public enum WatermarkPosition
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// 左上角
|
|||
|
|
/// </summary>
|
|||
|
|
TopLeftCorner,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 中上
|
|||
|
|
/// </summary>
|
|||
|
|
TopCenter,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 右上角
|
|||
|
|
/// </summary>
|
|||
|
|
TopRightCorner,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 左中
|
|||
|
|
/// </summary>
|
|||
|
|
CenterLeft,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 居中
|
|||
|
|
/// </summary>
|
|||
|
|
Center,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 右中
|
|||
|
|
/// </summary>
|
|||
|
|
CenterRight,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 左下角
|
|||
|
|
/// </summary>
|
|||
|
|
BottomLeftCorner,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 中下
|
|||
|
|
/// </summary>
|
|||
|
|
BottomCenter,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 右下角
|
|||
|
|
/// </summary>
|
|||
|
|
BottomRightCorner,
|
|||
|
|
/// <summary>
|
|||
|
|
/// 全屏平铺
|
|||
|
|
/// </summary>
|
|||
|
|
FullScreenTile,
|
|||
|
|
}
|
|||
|
|
}
|