none
C#windows编程添加水印图片失真 RRS feed

  • 问题

  • 我需要在一张图上添加多个水印,我的图片是png格式,而且是无背景的,最终保存也是png格式,但是图片出来,图像(不是图片周围哦,图像这里指有图案的地方)周围出现黑边,锯齿比较严重,而且图片上出现原图没有的多个黑点。
    我还发现最后一个添加的水印是没问题的,图像和原图一样,只是在他之前添加上去的水印图像周边就会有黑色边,而且每加多个水印,之前添加的水印周边的黑边越深范围越大。
    请大侠帮帮手看是什么问题
    我把我代码贴出来:
            /// <summary>
            /// 生成水印
            /// </summary>
            /// <param name="savePath">程序目录路径</param>
            /// <param name="body_path">主图片路径</param>
            /// <param name="favorite">结构体,作为水印的图片集合,每个对象有图片路径,位置x,y成员</param>
            /// <returns></returns>
            public string generateWinterMark(string savePath, string body_path, favoriteImage[] favorite)
            {
                //create a image object containing the photograph to watermark
                Image imgPhoto = Image.FromFile(body_path);
                int phWidth = imgPhoto.Width;
                int phHeight = imgPhoto.Height;

                //create a Bitmap the Size of the original photograph
                Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);

                //设置此 Bitmap 的分辨率。
                bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

                //load the Bitmap into a Graphics object
                Graphics grPhoto = Graphics.FromImage(bmPhoto);
                //Set the rendering quality for this Graphics object
                grPhoto.SmoothingMode = SmoothingMode.AntiAlias;//清除锯齿的呈现
                //haix
                for (int i = 0; i < favorite.Length; i++)
                {
                    //Draws the photo Image object at original size to the graphics object.
                    grPhoto.DrawImage(
                        imgPhoto,                               // Photo Image object
                        new Rectangle(0, 0, phWidth, phHeight), // Rectangle structure
                        0,                                      // x-coordinate of the portion of the source image to draw.
                        0,                                      // y-coordinate of the portion of the source image to draw.
                        phWidth,                                // Width of the portion of the source image to draw.
                        phHeight,                               // Height of the portion of the source image to draw.
                        GraphicsUnit.Pixel);                    // Units of measure


                    //------------------------------------------------------------
                    //Step #2 - Insert Property image,For example:hair,skirt,shoes etc.
                    //------------------------------------------------------------
                    //create a image object containing the watermark
                    Image imgWatermark = new Bitmap(favorite[i].imagePath);
                    int wmWidth = imgWatermark.Width;
                    int wmHeight = imgWatermark.Height;


                    //Create a Bitmap based on the previously modified photograph Bitmap
                    Bitmap bmWatermark = new Bitmap(bmPhoto);
                    bmWatermark.MakeTransparent(); //使默认的透明颜色对此 Bitmap 透明。

                    //bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
                    //Load this Bitmap into a new Graphic Object
                    Graphics grWatermark = Graphics.FromImage(bmWatermark);


                    int xPosOfWm = favorite[i].x;
                    int yPosOfWm = favorite[i].y;

                    //叠加
                    grWatermark.DrawImage(imgWatermark, new Rectangle(xPosOfWm, yPosOfWm, wmWidth, wmHeight),  //Set the detination Position
                    0,                  // x-coordinate of the portion of the source image to draw.
                    0,                  // y-coordinate of the portion of the source image to draw.
                    wmWidth,            // Watermark Width
                    wmHeight,      // Watermark Height
                    GraphicsUnit.Pixel, // Unit of measurment
                    null);   //ImageAttributes Object


                    //Replace the original photgraphs bitmap with the new Bitmap
                    imgPhoto = bmWatermark;

                    //grWatermark.Dispose();
                    //imgWatermark.Dispose();
                    //grPhoto.Dispose();               
                    //bmWatermark.Dispose();
                }
                //haix

                string nowTime = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString();
                nowTime += DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();

                string saveImagePath = savePath + "\\FA" + nowTime + ".png";

                //save new image to file system.
                imgPhoto.Save(saveImagePath, ImageFormat.Png);
                imgPhoto.Dispose();


                return saveImagePath;
            }


    问题补充:我刚又发现个问题,就是说图片中的图像周围用ps模糊下,黑边越明显


    新发现:我想这才是我的主要问题了,我发现水印图片的位置必须得在主图片的图像上,如果水印图片添加到主图的空白出,就会出现我那样的问题,但是这个问题有什么方法可解决啊,望各位大侠赐教,我的主要目的是要用多张图拼成一副完整的图,而且 各部分的图 在 没有图像的地方 不会遮住下面的图像,是不是有更好的方法。
    我之前试过用pictureBox装没副图,然后调节pictureBox的位置,但是pictureBox会出现没有图像的地方也会遮住下面的图像。

    2009年8月21日 14:53

答案

  •    问题终于解决了,代码中这句错了 Bitmap bmWatermark = new Bitmap(bmPhoto);改成Bitmap bmWatermark = new Bitmap(imgPhoto);就对了

    • 已标记为答案 梦里人 2009年8月23日 11:48
    2009年8月23日 11:48

全部回复

  • 你好!
         在绘图之前添加这行代码可以消除锯齿:
         g.SmoothingMode=SmoothingMode.AntiAlias;
    周雪峰
    2009年8月21日 16:13
    版主
  • 你好!
         在绘图之前添加这行代码可以消除锯齿:
         g.SmoothingMode=SmoothingMode.AntiAlias;
    周雪峰

         我的已经有添加这句了,但是还是有锯齿,但主要问题还不在这,图像的轮廓上有黑边,有的地方有,就像东西给烧焦了,而且在图片中本身应该是透明的地方出现黑点(我把图的背景去掉干净了,而且保存成png),我尝试将我的主体图片换成单色的图片,图像周边的轮廓就不是黑色了,和单色图片颜色一样,图像附近的小黑点颜色也变成单色图片的颜色。不知道这是什么问题。
    2009年8月21日 18:16
  • 推荐你看看这两篇:
    http://hi.baidu.com/jameszou/blog/item/52c1840a6ab5651d94ca6b96.html
    http://space.itpub.net/12639172/viewspace-497980
    http://hi.baidu.com/2009ajun
    2009年8月21日 22:03
  •       你好!
          你可以再一次用水印来替代背景颜色:ColorMap colorMap = new ColorMap();
          这样应该可以把那些黑点覆盖掉。
    2009年8月22日 9:02
  • 推荐你看看这两篇:
    http://hi.baidu.com/jameszou/blog/item/52c1840a6ab5651d94ca6b96.html
    http://space.itpub.net/12639172/viewspace-497980
    http://hi.baidu.com/2009ajun


         你好!我试了还是解决不了我的问题,我的需要在一张图上添加多个水印,我发现最后一个添加的水印是没问题的,图像和原图一样,只是在他之前添加上去的水印图像周边就会有黑色边,而且每加多个水印,之前添加的水印周边的黑边越深范围越大。
        我把我代码贴出来:
            /// <summary>
            /// 生成水印
            /// </summary>
            /// <param name="savePath">程序目录路径</param>
            /// <param name="body_path">主图片路径</param>
            /// <param name="favorite">结构体,作为水印的图片集合</param>
            /// <returns></returns>
            public string generateWinterMark(string savePath, string body_path, favoriteImage[] favorite)
            {
                //create a image object containing the photograph to watermark
                Image imgPhoto = Image.FromFile(body_path);
                int phWidth = imgPhoto.Width;
                int phHeight = imgPhoto.Height;

                //create a Bitmap the Size of the original photograph
                Bitmap bmPhoto = new Bitmap(phWidth, phHeight, PixelFormat.Format24bppRgb);

                //设置此 Bitmap 的分辨率。
                bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

                //load the Bitmap into a Graphics object
                Graphics grPhoto = Graphics.FromImage(bmPhoto);
                //Set the rendering quality for this Graphics object
                grPhoto.SmoothingMode = SmoothingMode.AntiAlias;//清除锯齿的呈现
                //haix
                for (int i = 0; i < favorite.Length; i++)
                {
                    //Draws the photo Image object at original size to the graphics object.
                    grPhoto.DrawImage(
                        imgPhoto,                               // Photo Image object
                        new Rectangle(0, 0, phWidth, phHeight), // Rectangle structure
                        0,                                      // x-coordinate of the portion of the source image to draw.
                        0,                                      // y-coordinate of the portion of the source image to draw.
                        phWidth,                                // Width of the portion of the source image to draw.
                        phHeight,                               // Height of the portion of the source image to draw.
                        GraphicsUnit.Pixel);                    // Units of measure


                    //------------------------------------------------------------
                    //Step #2 - Insert Property image,For example:hair,skirt,shoes etc.
                    //------------------------------------------------------------
                    //create a image object containing the watermark
                    Image imgWatermark = new Bitmap(favorite[i].imagePath);
                    int wmWidth = imgWatermark.Width;
                    int wmHeight = imgWatermark.Height;


                    //Create a Bitmap based on the previously modified photograph Bitmap
                    Bitmap bmWatermark = new Bitmap(bmPhoto);
                    bmWatermark.MakeTransparent(); //使默认的透明颜色对此 Bitmap 透明。

                    //bmWatermark.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
                    //Load this Bitmap into a new Graphic Object
                    Graphics grWatermark = Graphics.FromImage(bmWatermark);


                    int xPosOfWm = favorite[i].x;
                    int yPosOfWm = favorite[i].y;

                    //叠加
                    grWatermark.DrawImage(imgWatermark, new Rectangle(xPosOfWm, yPosOfWm, wmWidth, wmHeight),  //Set the detination Position
                    0,                  // x-coordinate of the portion of the source image to draw.
                    0,                  // y-coordinate of the portion of the source image to draw.
                    wmWidth,            // Watermark Width
                    wmHeight,      // Watermark Height
                    GraphicsUnit.Pixel, // Unit of measurment
                    null);   //ImageAttributes Object


                    //Replace the original photgraphs bitmap with the new Bitmap
                    imgPhoto = bmWatermark;

                    //grWatermark.Dispose();
                    //imgWatermark.Dispose();
                    //grPhoto.Dispose();               
                    //bmWatermark.Dispose();
                }
                //haix

                string nowTime = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString();
                nowTime += DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();

                string saveImagePath = savePath + "\\FA" + nowTime + ".png";

                //save new image to file system.
                imgPhoto.Save(saveImagePath, ImageFormat.Png);
                imgPhoto.Dispose();


                return saveImagePath;
            }
            期待你继续指点

    2009年8月22日 18:38
  •    问题终于解决了,代码中这句错了 Bitmap bmWatermark = new Bitmap(bmPhoto);改成Bitmap bmWatermark = new Bitmap(imgPhoto);就对了

    • 已标记为答案 梦里人 2009年8月23日 11:48
    2009年8月23日 11:48