龙亿

------ 细细口味人生中的每一杯苦咖啡.

导航

图片处理(给图片加水印)

Posted on 2009-09-19 17:20  龙亿  阅读(662)  评论(0编辑  收藏  举报

 using System;
 using System.Collections.Generic;
 using System.Text;
 using System.Drawing;
 using System.Drawing.Drawing2D;
 using System.Drawing.Imaging;
 using System.IO;
 
 namespace Loskiv.Utility
 {
     /**//// <summary>
     /// 名称:图片处理常用操作类
     /// 作者:loskiv
     /// 创建时间:2009-07-07
     /// </summary>
     public class ImageUtility
     {
 
         /**//// <summary>
         /// 获取指定mimeType的ImageCodecInfo
         /// </summary>
         private static ImageCodecInfo GetImageCodecInfo(string mimeType)
         {
             ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
             foreach (ImageCodecInfo ici in CodecInfo)
             {
                 if (ici.MimeType == mimeType) return ici;
             }
             return null;
         }
 
         /**//// <summary>
         ///  获取inputStream中的Bitmap对象
         /// </summary>
         public static Bitmap GetBitmapFromStream(Stream inputStream)
         {
             Bitmap bitmap = new Bitmap(inputStream);
             return bitmap;
         }
 
         /**//// <summary>
         /// 将Bitmap对象压缩为JPG图片类型
         /// </summary>
         /// </summary>
         /// <param name="bmp">源bitmap对象</param>
         /// <param name="saveFilePath">目标图片的存储地址</param>
         /// <param name="quality">压缩质量,越大照片越清晰,推荐80</param>
         public static void CompressAsJPG(Bitmap bmp, string saveFilePath, int quality)
         {
             EncoderParameter p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality); ;
             EncoderParameters ps = new EncoderParameters(1);
             ps.Param[0] = p;
             bmp.Save(saveFilePath, GetImageCodecInfo("image/jpeg"), ps);
             bmp.Dispose();
         }
 
         /**//// <summary>
         /// 将inputStream中的对象压缩为JPG图片类型
         /// </summary>
         /// <param name="inputStream">源Stream对象</param>
         /// <param name="saveFilePath">目标图片的存储地址</param>
         /// <param name="quality">压缩质量,越大照片越清晰,推荐80</param>
         public static void CompressAsJPG(Stream inputStream, string saveFilePath, int quality)
         {
             Bitmap bmp = GetBitmapFromStream(inputStream);
             CompressAsJPG(bmp, saveFilePath, quality);
         }
 
 
         /**//// <summary>
         /// 生成缩略图(JPG 格式)
         /// </summary>
         /// <param name="inputStream">包含图片的Stream</param>
         /// <param name="saveFilePath">目标图片的存储地址</param>
         /// <param name="width">缩略图的宽</param>
         /// <param name="height">缩略图的高</param>
         public static void ThumbAsJPG(Stream inputStream, string saveFilePath, int width, int height)
         {
             Image image = Image.FromStream(inputStream);
             if (image.Width == width && image.Height == height)
             {
                 CompressAsJPG(inputStream, saveFilePath, 80);
             }
             int tWidth, tHeight, tLeft, tTop;
             double fScale = (double)height / (double)width;
             if (((double)image.Width * fScale) > (double)image.Height)
             {
                 tWidth = width;
                 tHeight = (int)((double)image.Height * (double)tWidth / (double)image.Width);
                 tLeft = 0;
                 tTop = (height - tHeight) / 2;
             }
             else
             {
                 tHeight = height;
                 tWidth = (int)((double)image.Width * (double)tHeight / (double)image.Height);
                 tLeft = (width - tWidth) / 2;
                 tTop = 0;
             }
            if (tLeft < 0) tLeft = 0;
            if (tTop < 0) tTop = 0;

            Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            Graphics graphics = Graphics.FromImage(bitmap);

            //可以在这里设置填充背景颜色
            graphics.Clear(Color.White);
            graphics.DrawImage(image, new Rectangle(tLeft, tTop, tWidth, tHeight));
            image.Dispose();
            try
            {
                CompressAsJPG(bitmap, saveFilePath, 80);
            }
            catch
            {
                ;
            }
            finally
            {
                bitmap.Dispose();
                graphics.Dispose();
            }
        }

        /**//// <summary>
        /// 将Bitmap对象裁剪为指定JPG文件
        /// </summary>
        /// <param name="bmp">源bmp对象</param>
        /// <param name="saveFilePath">目标图片的存储地址</param>
       /// <param name="x">开始坐标x,单位:像素</param>
        /// <param name="y">开始坐标y,单位:像素</param>
       /// <param name="width">宽度:像素</param>
        /// <param name="height">高度:像素</param>
        public static void CutAsJPG(Bitmap bmp, string saveFilePath, int x, int y, int width, int height)
        {
            int bmpW = bmp.Width;
            int bmpH = bmp.Height;

            if (x >= bmpW || y >= bmpH)
            {
                CompressAsJPG(bmp, saveFilePath, 80);
                return;
            }

            if (x + width > bmpW)
            {
                width = bmpW - x;
            }

            if (y + height > bmpH)
            {
                height = bmpH - y;
            }

            Bitmap bmpOut = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(bmpOut);
            g.DrawImage(bmp, new Rectangle(0, 0, width, height), new Rectangle(x, y, width, height), GraphicsUnit.Pixel);
            g.Dispose();
            bmp.Dispose();
            CompressAsJPG(bmpOut, saveFilePath, 80);
        }

        /**//// <summary>
        /// 将Stream中的对象裁剪为指定JPG文件
        /// </summary>
        /// <param name="inputStream">源bmp对象</param>
        /// <param name="saveFilePath">目标图片的存储地址</param>
        /// <param name="x">开始坐标x,单位:像素</param>
        /// <param name="y">开始坐标y,单位:像素</param>
        /// <param name="width">宽度:像素</param>
        /// <param name="height">高度:像素</param>
        public static void CutAsJPG(Stream inputStream, string saveFilePath, int x, int y, int width, int height)
        {
           Bitmap bmp = GetBitmapFromStream(inputStream);
            CutAsJPG(bmp, saveFilePath, x, y, width, height);
        }


       图片水印操作#region 图片水印操作

        /**//// <summary>
        /// 给图片添加图片水印
        /// </summary>
        /// <param name="inputStream">包含要源图片的流</param>
        /// <param name="watermarkPath">水印图片的物理地址</param>
        /// <param name="saveFilePath">目标图片的存储地址</param>
        /// <param name="mp">水印位置</param>
        public static void AddPicWatermarkAsJPG(Stream inputStream, string watermarkPath, string saveFilePath, MarkPosition mp)
        {

            Image image = Image.FromStream(inputStream);
            Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(b);
            g.Clear(Color.White);
           g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.High;
           g.DrawImage(image, 0, 0, image.Width, image.Height);

            AddWatermarkImage(g, watermarkPath, mp, image.Width, image.Height);
            try
            {
                CompressAsJPG(b, saveFilePath, 80);
            }
            catch { ;}
            finally
            {
                b.Dispose();
                image.Dispose();
            }
       }

        /**//// <summary>
        /// 给图片添加图片水印
        /// </summary>
        /// <param name="sourcePath">源图片的存储地址</param>
        /// <param name="watermarkPath">水印图片的物理地址</param>
        /// <param name="saveFilePath">目标图片的存储地址</param>
        /// <param name="mp">水印位置</param>
        public static void AddPicWatermarkAsJPG(string sourcePath, string watermarkPath, string saveFilePath, MarkPosition mp)
       {
            if (File.Exists(sourcePath))
           {
                using (StreamReader sr = new StreamReader(sourcePath))
                {
                    AddPicWatermarkAsJPG(sr.BaseStream, watermarkPath, saveFilePath, mp);
                }
            }
        }
        /**//// <summary>
        /// 给图片添加文字水印        /// </summary>
        /// <param name="inputStream">包含要源图片的流</param>
        /// <param name="text">水印文字</param>
        /// <param name="saveFilePath">目标图片的存储地址</param>
        /// <param name="mp">水印位置</param>
        public static void AddTextWatermarkAsJPG(Stream inputStream, string text, string saveFilePath, MarkPosition mp)
        {

            Image image = Image.FromStream(inputStream);
            Bitmap b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
            Graphics g = Graphics.FromImage(b);
            g.Clear(Color.White);
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.High;
            g.DrawImage(image, 0, 0, image.Width, image.Height);

            AddWatermarkText(g, text, mp, image.Width, image.Height);

            try
            {
                CompressAsJPG(b, saveFilePath, 80);
            }
            catch { ;}
            finally
            {
                b.Dispose();
                image.Dispose();
            }
        }

        /**//// <summary>
        /// 给图片添加文字水印
        /// </summary>
        /// <param name="sourcePath">源图片的存储地址</param>
        /// <param name="text">水印文字</param>
        /// <param name="saveFilePath">目标图片的存储地址</param>
        /// <param name="mp">水印位置</param>
        public static void AddTextWatermarkAsJPG(string sourcePath, string text, string saveFilePath, MarkPosition mp)
        {
            if (File.Exists(sourcePath))
            {
                using (StreamReader sr = new StreamReader(sourcePath))
                {
                    AddTextWatermarkAsJPG(sr.BaseStream, text, saveFilePath, mp);
                }
            }
        }

        /**//// <summary>
        /// 添加文字水印
        /// </summary>
        /// <param name="picture">要加水印的原图像</param>
        /// <param name="text">水印文字</param>
        /// <param name="mp">添加的位置</param>
        /// <param name="width">原图像的宽度</param>
        /// <param name="height">原图像的高度</param>
        private static void AddWatermarkText(Graphics picture, string text, MarkPosition mp, int width, int height)
        {
            int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };
            Font crFont = null;
            SizeF crSize = new SizeF();
            for (int i = 0; i < 7; i++)
            {
                crFont = new Font("Arial", sizes[i], FontStyle.Bold);
                crSize = picture.MeasureString(text, crFont);

                if ((ushort)crSize.Width < (ushort)width)
                    break;
            }

            float xpos = 0;
            float ypos = 0;

            switch (mp)
            {
                case MarkPosition.MP_Left_Top:
                    xpos = ((float)width * (float).01) + (crSize.Width / 2);
                    ypos = (float)height * (float).01;
                    break;
                case MarkPosition.MP_Right_Top:
                    xpos = ((float)width * (float).99) - (crSize.Width / 2);
                    ypos = (float)height * (float).01;
                    break;
                case MarkPosition.MP_Right_Bottom:
                    xpos = ((float)width * (float).99) - (crSize.Width / 2);
                    ypos = ((float)height * (float).99) - crSize.Height;
                    break;
                case MarkPosition.MP_Left_Bottom:
                    xpos = ((float)width * (float).01) + (crSize.Width / 2);
                    ypos = ((float)height * (float).99) - crSize.Height;
                    break;
            }

            StringFormat StrFormat = new StringFormat();
            StrFormat.Alignment = StringAlignment.Center;

            SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
            picture.DrawString(text, crFont, semiTransBrush2, xpos + 1, ypos + 1, StrFormat);

            SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
            picture.DrawString(text, crFont, semiTransBrush, xpos, ypos, StrFormat);

            semiTransBrush2.Dispose();
            semiTransBrush.Dispose();

        }

        /**//// <summary>
        /// 添加图片水印
        /// </summary>
        /// <param name="picture">要加水印的原图像</param>
        /// <param name="waterMarkPath">水印文件的物理地址</param>
        /// <param name="mp">添加的位置</param>
        /// <param name="width">原图像的宽度</param>
        /// <param name="height">原图像的高度</param>
        private static void AddWatermarkImage(Graphics picture, string waterMarkPath, MarkPosition mp, int width, int height)
        {
            Image watermark = new Bitmap(waterMarkPath);

            ImageAttributes imageAttributes = new ImageAttributes();
            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},
                                                 new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
                                                 new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
                                                 new float[] {0.0f,  0.0f,  0.0f,  0.3f, 0.0f},
                                                 new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
                                             };

            ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

            imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

            int xpos = 0;
            int ypos = 0;
            int WatermarkWidth = 0;
            int WatermarkHeight = 0;
            double bl = 1d;
            if ((width > watermark.Width * 4) && (height > watermark.Height * 4))
            {
                bl = 1;
            }
            else if ((width > watermark.Width * 4) && (height < watermark.Height * 4))
            {
                bl = Convert.ToDouble(height / 4) / Convert.ToDouble(watermark.Height);

            }
            else

                if ((width < watermark.Width * 4) && (height > watermark.Height * 4))
                {
                    bl = Convert.ToDouble(width / 4) / Convert.ToDouble(watermark.Width);
                }
                else
                {
                    if ((width * watermark.Height) > (height * watermark.Width))
                    {
                        bl = Convert.ToDouble(height / 4) / Convert.ToDouble(watermark.Height);

                    }
                    else
                    {
                        bl = Convert.ToDouble(width / 4) / Convert.ToDouble(watermark.Width);

                    }

                }

            WatermarkWidth = Convert.ToInt32(watermark.Width * bl);
            WatermarkHeight = Convert.ToInt32(watermark.Height * bl);


            switch (mp)
            {
                case MarkPosition.MP_Left_Top:
                    xpos = 10;
                    ypos = 10;
                    break;
                case MarkPosition.MP_Right_Top:
                    xpos = width - WatermarkWidth - 10;
                    ypos = 10;
                    break;
                case MarkPosition.MP_Right_Bottom:
                    xpos = width - WatermarkWidth - 10;
                    ypos = height - WatermarkHeight - 10;
                    break;
                case MarkPosition.MP_Left_Bottom:
                    xpos = 10;
                    ypos = height - WatermarkHeight - 10;
                    break;
            }

            picture.DrawImage(watermark, new Rectangle(xpos, ypos, WatermarkWidth, WatermarkHeight), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);


            watermark.Dispose();
            imageAttributes.Dispose();
        }

        /**//// <summary>
        /// 水印的位置
        /// </summary>        public enum MarkPosition
        {
            /**//// <summary>
            /// 左上角
            /// </summary>
            MP_Left_Top,

            /**//// <summary>
            /// 左下角
            /// </summary>
            MP_Left_Bottom,

            /**//// <summary>
            /// 右上角
            /// </summary>
            MP_Right_Top,

            /**//// <summary>
            /// 右下角
            /// </summary>
            MP_Right_Bottom
        }


        #endregion

    }
}