2

I am using itextsharp for creating pdf and its working good, but now when I am trying to add a background image (as a watermark), and I want to change image color to black and white but don't know how doing that. I am posting screenshot and also code which I am using for added background image.

enter image description here

Code :

public class PdfWriterEvents : IPdfPageEvent
        {
            string watermarkText = string.Empty;

            public PdfWriterEvents(string watermark)
            {
                watermarkText = watermark;
            }
            public void OnStartPage(PdfWriter writer, Document document)
            {
                float width = document.PageSize.Width;
                float height = document.PageSize.Height;
                try
                {
                    PdfContentByte under = writer.DirectContentUnder;
                    Image image = Image.GetInstance(watermarkText);                     
                    image.ScaleToFit(275f, 275f);
                    image.SetAbsolutePosition(150, 300);
                    under.AddImage(image);
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex.Message);
                }
            }
            public void OnEndPage(PdfWriter writer, Document document) { }
            public void OnParagraph(PdfWriter writer, Document document, float paragraphPosition) { }
            public void OnParagraphEnd(PdfWriter writer, Document document, float paragraphPosition) { }
            public void OnChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) { }
            public void OnChapterEnd(PdfWriter writer, Document document, float paragraphPosition) { }
            public void OnSection(PdfWriter writer, Document document, float paragraphPosition, int depth, Paragraph title) { }
            public void OnSectionEnd(PdfWriter writer, Document document, float paragraphPosition) { }
            public void OnGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) { }
            public void OnOpenDocument(PdfWriter writer, Document document) { }
            public void OnCloseDocument(PdfWriter writer, Document document) { }
        }

For call this :

writer.PageEvent = new PdfWriterEvents(LogoImage);

So How can I change color to black and white like normal watermark image.

Thank you !

Herry
  • 77
  • 1
  • 12
  • 2
    Edit the background image source to Black-n-White, maybe? – boop_the_snoot Oct 07 '17 at 05:08
  • sorry, but how to do that can you explain me ? – Herry Oct 07 '17 at 05:12
  • edit the image file in image editor like photoshop. – Jeric Cruz Oct 07 '17 at 05:13
  • If you don't know how to edit the image in general, then a simple task would be to open the image in MS Paint(*best Image Editor EVER!!*), and use the `Fill` tool to color Green part of the image to Black or Grey. Else [try this](https://www.google.co.in/search?q=medical+plus+sign+grey+and+white&client=firefox-b-ab&dcr=0&source=lnms&tbm=isch&sa=X&ved=0ahUKEwismPmh4d3WAhVHL48KHWeRADAQ_AUICigB&biw=1366&bih=635) – boop_the_snoot Oct 07 '17 at 05:17
  • yes that i Know @JericCruz that we can edit image using photoshop or other editor tool but, I want to know is there any other option can able to change color of image by back-end code using itextsharp. – Herry Oct 07 '17 at 05:20

2 Answers2

1

You can change the image color in two ways:

  1. The obviously the easiest one: Use an image editor like MS Paint or Adobe Photoshop to change the Image content color.

  2. At runtime, as you stated in comments: "I want to know is there any other option can able to change color of image by back-end code using itextsharp". Instead of using itextsharp, you can try the below code:


static void Main(string[] args)
{
    try
    {
        Bitmap bmp = null;
        //The Source Directory in debug\bin\Big\
        string[] files = Directory.GetFiles("Big\\");
        foreach (string filename in files)
        {
           bmp = (Bitmap)Image.FromFile(filename);                    
           bmp = ChangeColor(bmp);
           string[] spliter = filename.Split('\\');
           //Destination Directory debug\bin\BigGreen\
           bmp.Save("BigGreen\\" + spliter[1]);
        }                                                 
     }
     catch (System.Exception ex)
     {
        Console.WriteLine(ex.ToString());
     }            
}        

public static Bitmap ChangeColor(Bitmap scrBitmap)
{
    //You can change your new color here. Red,Green,LawnGreen any..
    Color newColor = Color.Red;
    Color actualColor;            
    //make an empty bitmap the same size as scrBitmap
    Bitmap newBitmap = new Bitmap(scrBitmap.Width, scrBitmap.Height);
    for (int i = 0; i < scrBitmap.Width; i++)
    {
       for (int j = 0; j < scrBitmap.Height; j++)
       {
         //get the pixel from the scrBitmap image
         actualColor = scrBitmap.GetPixel(i, j);
         // > 150 because.. Images edges can be of low pixel color. if we set all pixel color to new then there will be no smoothness left.
         if (actualColor.A > 150)
             newBitmap.SetPixel(i, j, newColor);
         else
             newBitmap.SetPixel(i, j, actualColor);
      }
   }            
   return newBitmap;
}

Credits: DareDevil's answer


You can edit your image using the provided method.

PS: While you are done and satisfied with the result, upvote @DareDevil's answer, it's a brilliant find!

boop_the_snoot
  • 3,209
  • 4
  • 33
  • 44
  • its work but, it apply to whole image. i want as same image but in light black and white color – Herry Oct 10 '17 at 11:16
1

To start with, you used OnStartPage to create the background. This actually is the wrong thing to do. iText developers have stressed again and again that no content shall be added to the document in OnStartPage. Instead one should use OnEndPage which in your case does not impose any problem, so you should really do so.


If you have a single bitmap only, the best way surely is to open that bitmap in some image manipulation software and then change the colors to make the image optimal as watermark background.

If on the other hand you have many possible images to use as background, probably you even get an individual image for each new document, then you cannot tweak each image to its optimum manually anymore. Instead you can either manipulate the bitmap itself by some service or you can use PDF specific features to manipulate the image appearance.

E.g. with your page event listener I get this:

original green image in background

Covering the background with white using blend mode Hue this becomes:

Changed image colors hue to white

That appears pretty dark but we can lighten it up covering the background with light gray in blend mode Screen:

Lightened up image

To do so I moved the code from your PdfWriterEvents method OnStartPage to OnEndPage (see the start of my answer) and changed it like this:

public void OnEndPage(PdfWriter writer, Document document)
{
    float width = document.PageSize.Width;
    float height = document.PageSize.Height;
    try
    {
        iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(watermarkText);
        image.ScaleToFit(275f, 275f);
        image.SetAbsolutePosition(150, 300);

        PdfGState gStateHue = new PdfGState();
        gStateHue.BlendMode = new PdfName("Hue");

        PdfGState gStateScreen = new PdfGState();
        gStateScreen.BlendMode = new PdfName("Screen");

        PdfContentByte under = writer.DirectContentUnder;
        under.SaveState();
        under.SetColorFill(BaseColor.WHITE);
        under.Rectangle(document.PageSize.Left, document.PageSize.Bottom, document.PageSize.Width, document.PageSize.Height);
        under.Fill();
        under.AddImage(image);
        under.SetGState(gStateHue);
        under.SetColorFill(BaseColor.WHITE);
        under.Rectangle(document.PageSize.Left, document.PageSize.Bottom, document.PageSize.Width, document.PageSize.Height);
        under.Fill();
        under.SetGState(gStateScreen);
        under.SetColorFill(BaseColor.LIGHT_GRAY);
        under.Rectangle(document.PageSize.Left, document.PageSize.Bottom, document.PageSize.Width, document.PageSize.Height);
        under.Fill();
        under.RestoreState();
    }
    catch (Exception ex)
    {
        Console.Error.WriteLine(ex.Message);
    }
}

I copied the image from IconArchive.

mkl
  • 90,588
  • 15
  • 125
  • 265
  • **` PdfContentByte canvas = writer.DirectContentUnder; Image image = Image.GetInstance(watermarkText); image.ScaleToFit(275f, 275f); image.SetAbsolutePosition(165, 300); canvas.SaveState(); PdfGState state = new PdfGState(); state.FillOpacity = 0.1f; canvas.SetGState(state); canvas.AddImage(image); canvas.RestoreState(); `** -------------------------------- you are right , but before your code post I also try same but this way and its works for me but at last Thank you ! for response – Herry Oct 12 '17 at 04:35
  • hello! if I call this ( **`writer.PageEvent = new PdfWriterEvents(LogoImage);` **) before document.open() then its comes from first page and sometime add new page which is blank and if I call after document.open() then its not comes on first page its comes start from second page but same issues comes (sometime add new page which is blank ) so how to call this and where to call kindly please post it.. Thank you! – Herry Oct 12 '17 at 05:26
  • You have to set it before opening the document, otherwise you miss some events. And you furthermore should read what I wrote about using `OnStartPage` at the end of my answer because your observations are symptoms thereof. – mkl Oct 12 '17 at 07:18
  • Yes I had ready when you post this response after that i try to do with ` onEndPage ` than its works for me what I want Thank You ! – Herry Oct 12 '17 at 12:30
  • That's great. I'll stress that some more in the answer. – mkl Oct 12 '17 at 13:11