我在ASP.NET中动态给JPG图片加水印 文字,这个目标已经实现,但是保存之后发现,加了水印的图片对比原图片模糊很多,本来的图片层次分明,很漂亮,加了水印后只能用凑合来形容,虽然能看清,但是不能满足视觉需要。网上找了很多资料,大部分都是说怎么保证缩略图的质量,可我的图片处理前后大小没有改变,所以不存在缩略图相信肯定有让图片处理后质量不下降 的高招,恳请大虾们赐教!!谢谢!目标:C#处理JPG图片前后,保持图片质量不降低

解决方案 »

  1.   

    C#图片水印类 
    using System; 
    using System.Collections.Generic; 
    using System.Text; 
    using System.Drawing; 
    using System.IO; 
    using System.Drawing.Drawing2D; 
    using System.Drawing.Imaging; 
    namespace ECHX.BLL 

            /// <summary> 
        /// WaterMark 的摘要说明 
        /// </summary> 
        /// 
        /// <param name="strCopyright">要加入的文字 </param> 
        /// <param name="strMarkPath">水印图片路径 </param> 
        /// <param name="strPhotoPath">要加水印的图片路径 </param> 
        /// <param name="strSavePath">处理后的图片路径 </param> 
        /// <param name="iMarkRightSpace">水印在修改图片中距左边的宽度 </param> 
        /// <param name="iMarkButtomSpace">水印在修改图片中距底部的高度 </param> 
        /// <param name="iDiaphaneity">水印图片的透明度 </param> 
        /// <param name="iFontRightSpace">文字 </param> 
        /// <param name="iFontButtomSpace">文字 </param> 
        /// <param name="iFontDiaphaneity">文字 </param> 
        /// <param name="bShowCopyright">是否显示文字 </param> 
        /// <param name="bShowMarkImage">是否显示水印图片 </param>     public class WaterMark 
        { 
            #region  param 
            private string strCopyright,strMarkPath,strPhotoPath,strSavePath; 
            private int iMarkRightSpace, iMarkButtomSpace, iDiaphaneity; 
            private int iFontRightSpace = 0, iFontButtomSpace = 0, iFontDiaphaneity=80; 
            private int iFontSize = 10; 
            private bool bShowCopyright=true, bShowMarkImage=true; 
            #endregion         #region WaterMark 
            public WaterMark() 
            { 
                this.strCopyright  = ""; 
                this.strMarkPath    = null; 
                this.strPhotoPath  = null; 
                this.strSavePath    = null; 
                this.iDiaphaneity  = 70; 
                this.iMarkRightSpace    = 0; 
                this.iMarkButtomSpace  = 0; 
            }         /// <summary> 
            /// 主要用两样都加的 
            /// </summary> 
            public WaterMark(string copyright,string Path,string photoPath,string savePath) 
            { 
                this.strCopyright  = copyright; 
                this.strMarkPath    = Path; 
                this.strPhotoPath  = photoPath; 
                this.strSavePath    = savePath; 
                this.iDiaphaneity  =  70; 
                this.iMarkRightSpace    = 0; 
                this.iMarkButtomSpace  = 0; 
            } 
            #endregion         #region property         /// <summary> 
            /// 设置是否显示水印文字 
            /// </summary> 
            public bool ShowCopyright 
            { 
                set { this.bShowCopyright = value; } 
            }         /// <summary> 
            /// 设置是否显示水印图片 
            /// </summary> 
            public bool ShowMarkImage 
            { 
                set { this.bShowMarkImage = value; } 
            } 
            /// <summary> 
            /// 获取或设置要加入的文字 
            /// </summary> 
            public string Copyright 
            { 
                set { this.strCopyright = value; } 
            }         /// <summary> 
            /// 获取或设置加水印后的图片路径 
            /// </summary> 
            public string SavePath 
            { 
                get { return this.strSavePath; } 
                set { this.strSavePath = value; } 
            }         /// <summary> 
            /// 获取或设置水印图片路径 
            /// </summary> 
            public string MarkPath 
            { 
                get { return this.strMarkPath; } 
                set { this.strMarkPath = value; } 
            }         /// <summary> 
            /// 获取或设置要加水印图片的路径 
            /// </summary> 
            public string PhotoPath 
            { 
                get { return this.strPhotoPath; } 
                set { this.strPhotoPath = value; } 
            }         /// <summary> 
            /// 设置水印图片的透明度 
            /// </summary> 
            public int Diaphaneity 
            { 
                set { 
                    if(value > 0 && value <= 100) 
                        this.iDiaphaneity = value; 
                } 
            }         /// <summary> 
            /// 设置水印字体的透明度0-255 
            /// </summary> 
            public int FontDiaphaneity 
            { 
                set 
                { 
                    if (value >= 0 && value <= 255) 
                        this.iFontDiaphaneity = value; 
                } 
            }         /// <summary> 
            /// 设置水印图片在修改图片中距左边的高度 
            /// </summary> 
            public int MarkRightSpace 
            { 
                set { this.iMarkRightSpace = value; } 
            }         /// <summary> 
            /// 设置水印图片在修改图片中距底部的高度 
            /// </summary> 
            public int MarkButtomSpace 
            { 
                set { this.iMarkButtomSpace = value; } 
            }         /// <summary> 
            /// 设置水印字体在修改图片中距左边的距离 
            /// </summary> 
            public int FontRightSpace 
            { 
                set { iFontRightSpace = value; } 
            }         /// <summary> 
            /// 设置水印字体在修改图片中距底部的高度 
            /// </summary> 
            public int FontButtomSpace 
            { 
                set { iFontButtomSpace = value; } 
            }         #endregion       
            /// <summary> 
            /// 生成水印图片 
            /// </summary> 
            /// <returns> </returns> 
            public void createMarkPhoto() 
            { 
                Bitmap bmWater = null; 
                Image gPhoto = Image.FromFile(this.strPhotoPath); 
                int PhotoWidth  = gPhoto.Width; 
                int PhotoHeight = gPhoto.Height; 
                Bitmap bitPhoto = new Bitmap(PhotoWidth, PhotoHeight,PixelFormat.Format24bppRgb); 
                bitPhoto.SetResolution(gPhoto.HorizontalResolution,gPhoto.VerticalResolution);             try 
                { 
                    if (bShowCopyright) 
                    { 
                        Graphics grPhoto = Graphics.FromImage(bitPhoto); 
                        grPhoto.SmoothingMode = SmoothingMode.AntiAlias; 
                        grPhoto.DrawImage(gPhoto, new Rectangle(0, 0, PhotoWidth, PhotoHeight), 0, 0, PhotoWidth, PhotoHeight, GraphicsUnit.Pixel);                     Font crFont = new Font("楷体", iFontSize, FontStyle.Bold); 
                        SizeF crSize = grPhoto.MeasureString(strCopyright, crFont);                     //设置字体在图片中的位置 
                        float yPosFromBottom = PhotoHeight - iFontButtomSpace - (crSize.Height);                     //float xCenterOfImg = (phWidth/2); 
                        float xCenterOfImg = PhotoWidth - iFontRightSpace - (crSize.Width / 2); 
                        //设置字体居中                     StringFormat StrFormat = new StringFormat(); 
                        StrFormat.Alignment = StringAlignment.Center;                     //设置绘制文本的颜色和纹理 (Alpha=153) 
                        SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(this.iFontDiaphaneity, 0, 0, 0));                     //将版权信息绘制到图象上 
                        grPhoto.DrawString(strCopyright, crFont, semiTransBrush2, new PointF(xCenterOfImg, yPosFromBottom), StrFormat);                     gPhoto = bitPhoto; 
                        grPhoto.Dispose(); 
                    }                 if (bShowMarkImage) 
                    { 
                        //创建一个需要填充水银的Image对象 
                        Image imgWater = new Bitmap(strMarkPath); 
                        int iMarkWidth = imgWater.Width; 
                        int iMarkmHeight = imgWater.Height;                     Graphics grWater = null; 
                        if (bShowCopyright) 
                        { 
                            //在原来修改过的bmPhoto上创建一个水银位图 
                            bmWater = new Bitmap(bitPhoto); 
                            bmWater.SetResolution(gPhoto.HorizontalResolution, gPhoto.VerticalResolution); 
                        } 
                        else 
                        { 
                            bmWater = new Bitmap(gPhoto); 
                        }                     //将位图bmWater加载到Graphics对象 
                        grWater = Graphics.FromImage(bmWater); 
                        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, (float)iDiaphaneity/100f, 0.0f}, 
                        new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}}; 
                        ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements);                     imageAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);                     grWater.DrawImage(imgWater, new Rectangle((PhotoWidth - iMarkRightSpace - (iMarkWidth / 2)), (PhotoHeight - iMarkButtomSpace - (iMarkmHeight/2)), iMarkWidth, iMarkmHeight), 0, 0, iMarkWidth, iMarkmHeight, GraphicsUnit.Pixel, imageAttributes);                     gPhoto = bmWater; 
                        grWater.Dispose(); 
                        imgWater.Dispose(); 
                    } 
                    gPhoto.Save(strSavePath, ImageFormat.Jpeg); 
                } 
                finally 
                {             if (bitPhoto!=null) 
                    bitPhoto.Dispose();             if (bmWater != null) 
                    bmWater.Dispose();             gPhoto.Dispose(); 
              } 
                
            } 
        } 

      

  2.   

    谢谢shuiwenyu的热心回答,但是我想请问一下:这个类里面哪些代码是控制输出图片质量的呢?
    之前我也找到类似的代码试验过,可以加水印文字或水印图片 ,但是最后输出的图片质量不满意
      

  3.   

    谢谢shuiwenyu的热心回答,但是我想请问一下:这个类里面哪些代码是控制输出图片质量的呢?
    之前我也找到类似的代码试验过,可以加水印文字或水印图片 ,但是最后输出的图片质量不满意
      

  4.   

    到我的资源里下一个,bitmap -> int[,,], int[,,] -> image,在数组中对水印进行操作,然后再转换成 Image,效果应该好得多,我BLOG上的内容全是这样操作出来然后转换成最终图像的,如果内容不变,它的质量没有损失
      

  5.   

    To :zhoujk
    你说的东西我到你空间里没有看到哦?
      

  6.   

    下面是我给JPG图片加文字水印的代码,可能不是太完善,但是最后得到的图片确实没有处理前的图片质量高,总是有点糊糊的感觉,边缘感也不强
    欢迎各位指正:
    Bitmap bmWater = null;
         System.Drawing.Image gPhoto = System.Drawing.Image.FromFile(Server.MapPath(”img/66.jpg”)); 
        int PhotoWidth  = gPhoto.Width; 
        int PhotoHeight = gPhoto.Height; 
        Bitmap bitPhoto = new Bitmap(PhotoWidth, PhotoHeight,PixelFormat.Format24bppRgb); 
        bitPhoto.SetResolution(gPhoto.HorizontalResolution,gPhoto.VerticalResolution);    Graphics grPhoto = Graphics.FromImage(bitPhoto); 
         grPhoto.SmoothingMode = SmoothingMode.AntiAlias; 
         grPhoto.DrawImage(gPhoto, new Rectangle(0, 0, PhotoWidth, PhotoHeight), 0, 0, PhotoWidth, PhotoHeight, GraphicsUnit.Pixel);      Font crFont = new Font(”楷体”, 12, FontStyle.Bold); 
         SizeF crSize = grPhoto.MeasureString(”hujun”, crFont);      //设置字体在图片中的位置 
         float yPosFromBottom = PhotoHeight - 10 - (crSize.Height);      //float xCenterOfImg = (phWidth/2); 
         float xCenterOfImg = PhotoWidth - 10 - (crSize.Width / 2); 
         //设置字体居中      StringFormat StrFormat = new StringFormat(); 
         StrFormat.Alignment = StringAlignment.Center;      //设置绘制文本的颜色和纹理 (Alpha=153) 
         SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(255, 255, 255, 255));
         grPhoto.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
         //将信息绘制到图象上 
         grPhoto.DrawString(”hujun”, crFont, semiTransBrush2, new PointF(xCenterOfImg, yPosFromBottom), StrFormat);
         bitPhoto.Save(Response.OutputStream, ImageFormat.Jpeg);
      

  7.   

    不会C#
    grPhoto.SmoothingMode = SmoothingMode.AntiAlias
    这句代码的作用是让合成模式为自动反锯齿,也就是所谓的"模糊"
    你把这句去掉.
    另外,在定义新画布时不要定义位深度,这样才能保持原图的色彩.
    就是这句里面的加粗地方也去掉:
    Bitmap bitPhoto = new Bitmap(PhotoWidth, PhotoHeight,PixelFormat.Format24bppRgb);代码其他地方没什么异常.
      

  8.   

    bitPhoto.Save(Response.OutputStream, ImageFormat.Jpeg);
    图像保存的问题,默认的质量是60%            EncoderParameter p;
                EncoderParameters ps;            ps = new EncoderParameters(1);            p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
                ps.Param[0] = p;            ImageCodecInfo ii = GetCodecInfo("image/jpeg");
                bitPhoto.SaveResponse.OutputStream,ii,ps);        private ImageCodecInfo GetCodecInfo(string mimeType)
            {
                ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
                foreach (ImageCodecInfo ici in CodecInfo)
                {
                    if (ici.MimeType == mimeType) return ici;
                }
                return null;
            }
      

  9.   

    TO: dylike看了你的签名 专注GDI+ 后,我反复思考你所说的 “没有见过加了水印就变模糊的. ”本来我准备发2张对比图给你看,可当我把2张图片都保存,准备发的时候,发现2图的质量似乎是没什么差异,再一检查我的代码,才发现,我的初衷是把网页作为图片输出的,所以不是把图保存出来,在加水印并保存图后,图片是没有质量损失,但是我要把网页作为图片输出的时候就看到很模糊的图片,这就是2者的差异谢谢你!
      

  10.   

    To: softlove03看到你的回复,我眼前一亮,或许,你才是神啊!!你的回答似乎是我解决问题的关键,图像保存的问题,默认的质量是60%我被这个观点吸引了,现在赶紧去试验一下回头见
      

  11.   

    通过softlove03 的友情提示,我的问题已经解决了,谢谢各位热心的参与!