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

来源:互联网 发布:岁月如歌歌词含义 知乎 编辑:程序博客网 时间:2024/04/29 14:10
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)                {                    //以jpg格式保存缩略图                    bitmap.Save(thumbnailPath, ImageFormat.Jpeg);                }                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      //中心    }}

1 0
原创粉丝点击