您的位置:首页 > 编程语言 > C#

C# 图片缩略图,图片水印,文字水印

2017-02-03 15:48 405 查看
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace Jayzai.ZongJie.Common
{
/// <summary>
/// 缩略图帮助类
/// </summary>
public class ThumbnailHelper
{
/// <summary>
/// 创建缩略图
/// </summary>
/// <param name="originalPath">原图片路径</param>
/// <param name="thumbnailPath">保存缩略图的路径</param>
/// <param name="mode">压缩模式</param>
/// <param name="width">缩略图的宽</param>
/// <param name="height">缩略图的高</param>
/// <param name="flag">设置压缩质量(数字越小压缩率越高)[1-100]</param>
public static bool MakeThumbnail(string originalPath, string thumbnailPath, ThumbnailMode mode, int width = 0, int height = 0, int flag = 0)
{
//从指定的文件创建
System.Drawing.Image originalImage = System.Drawing.Image.FromFile(originalPath);
//原图片的宽、高
int ow = originalImage.Width;
int oh = originalImage.Height;

int x = 0;
int y = 0;
int Nwidth = width;//新宽
int Nheight = height;//新高

//创建的模式
switch (mode)
{
case ThumbnailMode.HW://指定高宽
break;
case ThumbnailMode.W://指定宽,高按比例
Nheight = originalImage.Height * width / originalImage.Width;
break;
case ThumbnailMode.H://指定高,宽按比例
Nwidth = originalImage.Width * height / originalImage.Height;
break;
case ThumbnailMode.Cut://指定高宽裁减(不变形)
if ((double)originalImage.Width / (double)originalImage.Height > (double)Nwidth / (double)Nheight)
{
oh = originalImage.Height;
ow = originalImage.Height * Nwidth / Nheight;
y = 0;
x = (originalImage.Width - ow) / 2;
}
else
{
ow = originalImage.Width;
oh = originalImage.Width * height / Nwidth;
x = 0;
y = (originalImage.Height - oh) / 2;
}
break;
default:
break;
}

//新建一个bmp图片
Image bitmap = new Bitmap(Nwidth, Nheight);
//新建一个画布
Graphics g = Graphics.FromImage(bitmap);
//设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//清空画布并以透明背景色填充
g.Clear(System.Drawing.Color.Transparent);
//在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(originalImage, new Rectangle(0, 0, Nwidth, Nheight)
, new Rectangle(x, y, ow, oh)
, GraphicsUnit.Pixel);
bool result = false;
try
{
if (flag == 0)
{
//保存缩略图格式
             ImageFormat imageFormat = ImageFormat.Jpeg;
             switch (extension.ToLower())
             {
               case ".png":
                   imageFormat = ImageFormat.Png;
                   break;
               case ".bmp":
                  imageFormat = ImageFormat.Bmp;
                   break;
               case ".gif":
                   imageFormat = ImageFormat.Gif;
                   break;
                case ".icon":
                   imageFormat = ImageFormat.Icon;
                  break;
                default:
                  break;
              }
              bitmap.Save(thumbnailPath, imageFormat);
}
else
{
//以下代码为保存图片时,设置压缩质量
EncoderParameters ep = new EncoderParameters();
long[] qy = new long[1];
qy[0] = flag;//设置压缩的比例1-100
EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
ep.Param[0] = eParam;

ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpegICIinfo = null;
for (int i = 0; i < arrayICI.Length; i++)
{
if (arrayICI[i].FormatDescription.Equals("JPEG"))
{
jpegICIinfo = arrayICI[i];
break;
}
}
bitmap.Save(thumbnailPath, jpegICIinfo, ep);
}
result = true;
}
catch (Exception)
{
thumbnailPath = originalPath;
}
finally
{
if (originalImage != null)
originalImage.Dispose();
if (bitmap != null)
bitmap.Dispose();
if (g != null)
g.Dispose();
}
return result;
}

/// <summary>
/// 获取原图旋转角度(IOS和Android相机拍的照片)
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static int ReadPictureDegree(string path)
{
int rotate = 0;
using (var image = System.Drawing.Image.FromFile(path))
{
foreach (var prop in image.PropertyItems)
{
if (prop.Id == 0x112)
{
if (prop.Value[0] == 6)
rotate = 90;
if (prop.Value[0] == 8)
rotate = -90;
if (prop.Value[0] == 3)
rotate = 180;
prop.Value[0] = 1;
}
}
}
return rotate;
}

/// <summary>
/// 旋转
/// </summary>
/// <param name="path"></param>
/// <param name="rotateFlipType"></param>
/// <returns></returns>
public static bool KiRotate(string path, RotateFlipType rotateFlipType)
{
try
{
using (Bitmap bitmap = new Bitmap(path))
{
bitmap.RotateFlip(rotateFlipType);
bitmap.Save(path);
}
return true;
}
catch (Exception ex)
{
return false;
}
}
}

/// <summary>
/// 水印图片的操作管理
/// </summary>
public class ImageHelper
{
/// <summary>
/// 添加图片水印
/// </summary>
/// <param name="originalPath">源图片路径</param>
/// <param name="waterPath">水印图片路径</param>
/// <param name="alpha">透明度(0.1F-1.0F数值越小透明度越高)</param>
/// <param name="position">位置</param>
/// <param name="SavePath" >保存图片的路径</param>
/// <returns></returns>
public static void AddImageWaterMark(string originalPath, string waterPath, float alpha, ImagePosition position, string savePath)
{
Image imgPhoto = null;//源图
Bitmap bmPhoto = null;
Graphics grPhoto = null;

Image imgWaterMark = null;//水印
Bitmap bmWatermark = null;
Graphics grWatermark = null;
try
{
#region 判断参数是否有效
if (string.IsNullOrEmpty(originalPath) || string.IsNullOrEmpty(waterPath) || alpha < 0 || string.IsNullOrEmpty(savePath))
return;

if (!File.Exists(originalPath))
{
throw new FileNotFoundException("The file don't exist!");
}

//// 源图片,水印图片全路径和对应的扩展名
string originalExtension = Path.GetExtension(originalPath).ToLower();
string waterExtension = Path.GetExtension(waterPath).ToLower();
//
// 判断文件是否存在,以及类型是否正确
//
if (!System.IO.File.Exists(originalPath) ||
!System.IO.File.Exists(originalPath) || (
originalExtension != ".gif" &&
originalExtension != ".jpg" &&
originalExtension != ".png") || (
waterExtension != ".gif" &&
waterExtension != ".jpg" &&
waterExtension != ".png"))
{
return;
}
#endregion
//
// 将需要加上水印的图片装载到Image对象中
//
using (FileStream fs = new FileStream(originalPath, FileMode.Open))
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((int)fs.Length);
MemoryStream ms = new MemoryStream(bytes);
imgPhoto = System.Drawing.Image.FromStream(ms);
}
}
if (imgPhoto == null)
return;
//
// 确定其长宽
//
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;
//
// 封装 GDI+ 位图,此位图由图形图像及其属性的像素数据组成。
//
bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
//
// 设定分辨率
//
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
//
// 定义一个绘图画面用来装载位图
//
grPhoto = Graphics.FromImage(bmPhoto);

//SmoothingMode:指定是否将平滑处理(消除锯齿)应用于直线、曲线和已填充区域的边缘。
// 成员名称  说明
// AntiAlias   指定消除锯齿的呈现。
// Default    指定不消除锯齿。
// HighQuality 指定高质量、低速度呈现。
// HighSpeed  指定高速度、低质量呈现。
// Invalid    指定一个无效模式。
// None     指定不消除锯齿。
grPhoto.SmoothingMode = SmoothingMode.AntiAlias;
//
// 第一次描绘,将我们的底图描绘在绘图画面上
//
grPhoto.DrawImage(imgPhoto,         //  要添加水印的图片
new Rectangle(0, 0, phWidth, phHeight),// 根据要添加的水印图片的宽和高
0,                    //X方向从0点开始描绘
0,                    // Y方向
phWidth,              // X方向描绘长度
phHeight,             // Y方向描绘长度
GraphicsUnit.Pixel);  // 描绘的单位,这里用的是像素

//
//同样,由于水印是图片,我们也需要定义一个Image来装载它
//
//imgWaterMark = new Bitmap(waterPath);
imgWaterMark = Image.FromFile(waterPath);
//
// 获取水印图片的高度和宽度
//
int wmWidth = imgWaterMark.Width;
int wmHeight = imgWaterMark.Height;
//
// 与底图一样,我们需要一个位图来装载水印图片。并设定其分辨率
//
bmWatermark = new Bitmap(bmPhoto);
bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
//
// 继续,将水印图片装载到一个绘图画面grWatermark
//
grWatermark = Graphics.FromImage(bmWatermark);
//
//ImageAttributes 对象包含有关在呈现时如何操作位图和图元文件颜色的信息。
//  
ImageAttributes imageAttributes = new ImageAttributes();
//
//Colormap: 定义转换颜色的映射
//
ColorMap colorMap = new ColorMap();
//
//我的水印图被定义成拥有绿色背景色的图片被替换成透明
//
colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);

ColorMap[] remapTable = { colorMap };
imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

float[][] colorMatrixElements = {
                    new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // red红色
                    new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, //green绿色
                    new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, //blue蓝色   
                    new float[] {0.0f, 0.0f, 0.0f, alpha, 0.0f}, //透明度  
                    new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}};//

// ColorMatrix:定义包含 RGBA 空间坐标的 5 x 5 矩阵。
// ImageAttributes 类的若干方法通过使用颜色矩阵调整图像颜色。
ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);
imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

//
//上面设置完颜色,下面开始设置位置
//
int xPosOfWm;
int yPosOfWm;
switch (position)
{
case ImagePosition.BottomMiddle:
xPosOfWm = (phWidth - wmWidth) / 2;
yPosOfWm = phHeight - wmHeight - 10;
break;
case ImagePosition.Center:
xPosOfWm = (phWidth - wmWidth) / 2;
yPosOfWm = (phHeight - wmHeight) / 2;
break;
case ImagePosition.LeftBottom:
xPosOfWm = 10;
yPosOfWm = phHeight - wmHeight - 10;
break;
//case ImagePosition.LeftTop:
//    xPosOfWm = 10;
//    yPosOfWm = 10;
//    break;
case ImagePosition.LeftTop:
xPosOfWm = 0;
yPosOfWm = 0;
break;
case ImagePosition.RightTop:
xPosOfWm = phWidth - wmWidth - 10;
yPosOfWm = 10;
break;
case ImagePosition.RigthBottom:
xPosOfWm = phWidth - wmWidth - 10;
yPosOfWm = phHeight - wmHeight - 10;
break;
case ImagePosition.TopMiddle:
xPosOfWm = (phWidth - wmWidth) / 2;
yPosOfWm = 10;
break;
default:
xPosOfWm = 10;
yPosOfWm = phHeight - wmHeight - 10;
break;
}

// 第二次绘图,把水印印上去
//
grWatermark.DrawImage(imgWaterMark,
new Rectangle(xPosOfWm,
yPosOfWm,
wmWidth,
wmHeight),
0,
0,
wmWidth,
wmHeight,
GraphicsUnit.Pixel,
imageAttributes);

imgPhoto = bmWatermark;
//
// 保存文件到服务器的文件夹里面
//
imgPhoto.Save(savePath, ImageFormat.Jpeg);
}
catch (Exception ex)
{
LogHelper.Error("AddImageWaterMark", ex);
}
finally
{
if (imgWaterMark != null)
imgWaterMark.Dispose();
if (bmWatermark != null)
bmWatermark.Dispose();
if (grWatermark != null)
grWatermark.Dispose();

if (imgPhoto != null)
imgPhoto.Dispose();
if (bmPhoto != null)
bmPhoto.Dispose();
if (grPhoto != null)
grPhoto.Dispose();
}
}

/// <summary>
/// 在图片上添加水印文字
/// </summary>
/// <param name="originalPath">源图片路径</param>
/// <param name="waterWords">需要添加到图片上的文字</param>
/// <param name="alpha">透明度(0.1F-1.0F数值越小透明度越高)</param>
/// <param name="position">位置</param>
/// <param name="savePath">保存路径</param>
/// <returns></returns>
public static void AddWordsWaterMark(string originalPath, string waterWords, float alpha, ImagePosition position, string savePath)
{
Image imgPhoto = null;
Bitmap bmPhoto = null;
Graphics grPhoto = null;
try
{
#region 判断参数是否有效
if (string.IsNullOrEmpty(originalPath) || string.IsNullOrEmpty(waterWords) || alpha < 0 || string.IsNullOrEmpty(savePath))
return;

if (!File.Exists(originalPath))
{
throw new FileNotFoundException("The file don't exist!");
}

//// 源图片全路径和对应的扩展名
string fileOriginalExtension = System.IO.Path.GetExtension(originalPath).ToLower();
//
// 判断文件是否存在,以及类型是否正确
//
if (!System.IO.File.Exists(originalPath) || (
fileOriginalExtension != ".gif" &&
fileOriginalExtension != ".jpg" &&
fileOriginalExtension != ".png"))
{
return;
}
#endregion
//
// 将需要加上水印的图片装载到Image对象中
//
using (FileStream fs = new FileStream(originalPath, FileMode.Open))
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((int)fs.Length);
MemoryStream ms = new MemoryStream(bytes);
imgPhoto = System.Drawing.Image.FromStream(ms);
}
}
if (imgPhoto == null)
return;
//
//获取图片的宽和高
//
int phWidth = imgPhoto.Width;
int phHeight = imgPhoto.Height;
//
//建立一个bitmap,和我们需要加水印的图片一样大小
//
bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);
//SetResolution:设置此 Bitmap 的分辨率
//这里直接将我们需要添加水印的图片的分辨率赋给了bitmap
bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
//Graphics:封装一个 GDI+ 绘图图面。
grPhoto = Graphics.FromImage(bmPhoto);

//设置图形的品质
//SmoothingMode:指定是否将平滑处理(消除锯齿)应用于直线、曲线和已填充区域的边缘。
// 成员名称  说明
// AntiAlias   指定消除锯齿的呈现。
// Default    指定不消除锯齿。
// HighQuality 指定高质量、低速度呈现。
// HighSpeed  指定高速度、低质量呈现。
// Invalid    指定一个无效模式。
// None     指定不消除锯齿。
grPhoto.SmoothingMode = SmoothingMode.AntiAlias;

//将我们要添加水印的图片按照原始大小描绘(复制)到图形中
grPhoto.DrawImage(imgPhoto,        //  要添加水印的图片
new Rectangle(0, 0, phWidth, phHeight), // 根据要添加的水印图片的宽和高
0,                             // X方向从0点开始描绘
0,                             // Y方向
phWidth,                       // X方向描绘长度
phHeight,                      // Y方向描绘长度
GraphicsUnit.Pixel);           // 描绘的单位,这里用的是像素

//根据图片的大小我们来确定添加上去的文字的大小
//在这里我们定义一个数组来确定
int[] sizes = new int[] { 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4 };

//字体
Font crFont = null;
//矩形的宽度和高度,SizeF有三个属性,分别为Height高,width宽,IsEmpty是否为空
SizeF crSize = new SizeF();

//利用一个循环语句来选择我们要添加文字的型号
//直到它的长度比图片的宽度小
for (int i = 0; i < 7; i++)
{
crFont = new Font("黑体", sizes[i], FontStyle.Bold);

//测量用指定的 Font 对象绘制并用指定的 StringFormat 对象格式化的指定字符串。
crSize = grPhoto.MeasureString(waterWords, crFont);
// ushort 关键字表示一种整数数据类型
if ((ushort)crSize.Width < (ushort)phWidth)
break;
}

//截边5%的距离,定义文字显示(由于不同的图片显示的高和宽不同,所以按百分比截取)
int yPixlesFromBottom = (int)(phHeight * .05);

//定义在图片上文字的位置
float wmHeight = crSize.Height;
float wmWidth = crSize.Width;

float xPosOfWm;
float yPosOfWm;
switch (position)
{
case ImagePosition.BottomMiddle:
xPosOfWm = phWidth / 2;
yPosOfWm = phHeight - wmHeight - 10;
break;
case ImagePosition.Center:
xPosOfWm = phWidth / 2;
yPosOfWm = phHeight / 2;
break;
case ImagePosition.LeftBottom:
xPosOfWm = wmWidth;
yPosOfWm = phHeight - wmHeight - 10;
break;
case ImagePosition.LeftTop:
xPosOfWm = wmWidth / 2;
yPosOfWm = wmHeight / 2;
break;
case ImagePosition.RightTop:
xPosOfWm = phWidth - wmWidth - 10;
yPosOfWm = wmHeight;
break;
case ImagePosition.RigthBottom:
xPosOfWm = phWidth - wmWidth - 10;
yPosOfWm = phHeight - wmHeight - 10;
break;
case ImagePosition.TopMiddle:
xPosOfWm = phWidth / 2;
yPosOfWm = wmWidth;
break;
default:
xPosOfWm = wmWidth;
yPosOfWm = phHeight - wmHeight - 10;
break;
}

//封装文本布局信息(如对齐、文字方向和 Tab 停靠位),显示操作(如省略号插入和国家标准 (National) 数字替换)和 OpenType 功能。
StringFormat StrFormat = new StringFormat();
//定义需要印的文字居中对齐
StrFormat.Alignment = StringAlignment.Center;

//SolidBrush:定义单色画笔。画笔用于填充图形形状,如矩形、椭圆、扇形、多边形和封闭路径。
//这个画笔为描绘阴影的画笔,呈灰色
int m_alpha = Convert.ToInt32(255 * alpha);
//SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(m_alpha, 0, 0, 0));

//描绘文字信息,这个图层向右和向下偏移一个像素,表示阴影效果
//DrawString 在指定矩形并且用指定的 Brush 和 Font 对象绘制指定的文本字符串。
//grPhoto.DrawString(waterWords,            //string of text
//              crFont,                     //font
//              semiTransBrush2,            //Brush
//              new PointF(xPosOfWm + 1, yPosOfWm + 1), //Position
//              StrFormat);

//从四个 ARGB 分量(alpha、红色、绿色和蓝色)值创建 Color 结构,这里设置透明度为153
//这个画笔为描绘正式文字的笔刷,呈白色
//SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));

//第二次绘制这个图形,建立在第一次描绘的基础上
//grPhoto.DrawString(waterWords,         //string of text
//              crFont,                  //font
//              semiTransBrush,          //Brush
//              new PointF(xPosOfWm, yPosOfWm), //Position
//              StrFormat);

//声明矩形域
RectangleF textArea = new RectangleF(xPosOfWm - (wmWidth / 2) + 2, yPosOfWm + 5, wmWidth, wmHeight + 10);
Brush whiteBrush = new SolidBrush(Color.White);   //白笔刷,画文字用
Brush blackBrush = new SolidBrush(Color.FromArgb(m_alpha, 0, 0, 0));   //灰色笔刷,画背景用
grPhoto.FillRectangle(blackBrush, xPosOfWm - (wmWidth / 2) + 2, yPosOfWm, wmWidth, wmHeight + 10);
grPhoto.DrawString(waterWords, crFont, whiteBrush, textArea);

//imgPhoto是我们建立的用来装载最终图形的Image对象
//bmPhoto是我们用来制作图形的容器,为Bitmap对象
imgPhoto = bmPhoto;
//将grPhoto保存
imgPhoto.Save(savePath, ImageFormat.Jpeg);
}
catch (Exception ex)
{
LogHelper.Error("AddWordsWaterMark", ex);
}
finally
{
if (imgPhoto != null)
imgPhoto.Dispose();
if (bmPhoto != null)
bmPhoto.Dispose();
if (grPhoto != null)
grPhoto.Dispose();
}
}
}

/// <summary>
/// 压缩模式
/// </summary>
public enum ThumbnailMode
{
/// <summary>
/// 指定宽高压缩
/// </summary>
HW = 0,
/// <summary>
/// 指定宽 高按等比例压缩
/// </summary>
W = 1,
/// <summary>
/// 指定高 宽按等比例压缩
/// </summary>
H = 2,
/// <summary>
/// Cut
/// </summary>
Cut = 3
}

/// <summary>
/// 图片位置
/// </summary>
public enum ImagePosition
{
LeftTop,    //左上
LeftBottom,  //左下
RightTop,    //右上
RigthBottom, //右下
TopMiddle,   //顶部居中
BottomMiddle, //底部居中
Center      //中心
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C#图片处理类
相关文章推荐