3

I'm trying to add watermark to image and save it at best quality, but when saving JPEG watermark has poor quality (but quality of main image is good).

string wtrSrc = @"D:\watermark.png";
string imgSrc = @"D:\image.jpg";
string imgOutJPG = @"D:\result.jpg";          
string imgOutPNG = @"D:\result.png";

// create new image
Bitmap imgOutput = new Bitmap(imgSrc);
Graphics outputGraphics = Graphics.FromImage(imgOutput);

// image quality
outputGraphics.CompositingQuality = CompositingQuality.HighQuality;
outputGraphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
outputGraphics.SmoothingMode = SmoothingMode.HighQuality;
outputGraphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

// create watermark image
System.Drawing.Image wtrmark = System.Drawing.Image.FromFile(wtrSrc);        

// add waternark
float wtrmarkX = 10;
float wtrmarkY = 10;
outputGraphics.DrawImage(wtrmark, wtrmarkX, wtrmarkY);

//set jpeg quality    
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
myEncoderParameters.Param[0] = myEncoderParameter;

// save result
imgOutput.Save(imgOutJPG, GetEncoder(ImageFormat.Jpeg), myEncoderParameters);
imgOutput.Save(imgOutPNG, ImageFormat.Png);

// clean
wtrmark.Dispose();
imgOutput.Dispose();
outputGraphics.Dispose();

......

    // ImageCodecInfo 
    private ImageCodecInfo GetEncoder(ImageFormat format)
    {

        ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

        foreach (ImageCodecInfo codec in codecs)
        {
            if (codec.FormatID == format.Guid)
            {
                return codec;
            }
        }
        return null;
    }

PNG saving works well, but I need to save JPEG. Here's the difference between PNG and JPEG https://i.stack.imgur.com/CqwgZ.jpg

I followed this article http://www.codeproject.com/Articles/2927/Creating-a-Watermarked-Photograph-with-GDI-for-NET and get the same result.

Is there a way to make watermark on JPEG looks good?

user1032559
  • 1,577
  • 1
  • 14
  • 16
  • Could your problem be a transparency in the source image such as http://stackoverflow.com/questions/6513633/c-convert-transparent-png-to-jpg-with-non-black-background-color? – Bryan Roberts May 03 '13 at 16:26
  • No, I tried to use as watermark simple JPEG image and result is the same. Here is example - http://i.imgur.com/SZQuEyR.jpg?1 – user1032559 May 03 '13 at 19:11
  • Have you tried InterpolationMode.InterpolationModeHighQualityBicubic ? – Matt Johnson May 05 '13 at 19:25
  • Yes, the same result. – user1032559 May 06 '13 at 07:49
  • I simplified the issue, but still with no result. Here the link - http://stackoverflow.com/questions/16373621/c-reduced-image-quality-when-saving-jpeg-at-100-quality – user1032559 May 06 '13 at 07:53
  • Your question is not about image watermarking but about plain image compression it seems. Your title is misleading. –  Oct 14 '15 at 11:20

1 Answers1

1

First intall Imagemagick in C:\Imagemagick folder in windows using

http://www.imagemagick.org/download/binaries/ImageMagick-6.8.8-7-Q16-x86-dll.exe

while installation add C:\ImageMagick; in PATH enviornment variable

and use below code for we b service

    using System.IO;
    using System.Drawing;

    [WebMethod]
        public Byte[] WatermarkImage(Byte[] image)
        {
    MemoryStream ms = new MemoryStream(image);
    Image image2 = Image.FromStream(ms);
    image2.Save(Server.MapPath("~") + "\\imageTest.jpg");
    string strCmdText;
    strCmdText = "/C convert.exe -draw \"gravity south fill black text 0,0 'Parth' \" \"" + Server.MapPath("~") +"\\imageTest.jpg \" \""+Server.MapPath("~") +"\\imageTest_result.jpg \"";
    System.Diagnostics.Process.Start("CMD.exe", strCmdText);
    System.Threading.Thread.Sleep(1000);
    byte[] imgdata = System.IO.File.ReadAllBytes(Server.MapPath("~") +"\\imageTest_result.jpg");
    return imgdata;
        }

Use in your web page

      protected void Button1_Click(object sender, EventArgs e)
         {
             if (this.FileUpload1.HasFile)
             {
        if (FileUpload1.PostedFile.ContentType == "image/jpeg")
        {
            if (FileUpload1.PostedFile.ContentLength < 512000)
            {
                string filename = Path.GetFileName(FileUpload1.FileName);
                FileUpload1.SaveAs(Server.MapPath("~") + "\\" + filename);
                Watermark w = new Watermark();
                Byte[] b = w.WatermarkImage(GetBytesFromFile(Server.MapPath("~") + "\\" + filename));
                MemoryStream ms = new MemoryStream(b);
                System.Drawing.Image image2 = System.Drawing.Image.FromStream(ms);
                image2.Save(Server.MapPath("~") + "\\imageTest_op.jpg");
                Image1.ImageUrl = "imageTest_op.jpg";
            }
                 }
             }
         }
prem30488
  • 2,828
  • 2
  • 25
  • 57