Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.


Edit Textcolor in existing PDF

  • Peter


    I need to edit the Textcolor of existing PDF-Documents. Is this possible with PDFClown?

    Thank you for help.

    • Doug Pickering
      Doug Pickering

      Hi Peter,

      I am using PDFClown more and more and I can say without a shadow of a doubt that it is possible.  Have a look through the samples and your will find a few that modify the contents of existing PDF documents.  If I were going to change the textcolor I would probably start with one of the samples and modify it.  I am sure Stefano will be able to point you in the right direction when he replies.



    • Peter

      Hi Doug,

      thanx for your reply. I found the ContentTweakingSample and try to adapt it for my purpose. In the sample SetLineWidth is used and i try replace this with SetFillColor. But while for the SetLineWidth exists getValue and SetValue methods, for SetFillColor only an getComponents method is in the API-documentation. So SetFillColor is readonly?

      all other text-related samples where SetFillColor is used, are for text-creatig only, so any further help is welcome.

    • Hi all
      I'm sorry to have lurked for several days without responding, but I was fully focused on the fresh 0.0.7 release. Now, as the release has been published, I can take a breath. ;-)
      Anyway, I wanna assure everybody visiting this forum that, even when I don't post an answer to a request, I always evaluate them (so don't feel uncomfortable if I seem to ignore some threads!).

      Thank you Peter for your request; user requests like yours are really important to let the library evolve towards richer and broader perspectives, different points of view and scenarios.

      As Doug suggested text color editing can be done with PDF Clown, but to do it at an acceptable high level (to say: avoiding to manually deal with color space dictionary selection), there are some minor interface details that limit the current release (for example, PrimitiveFilter doesn't allow to set the current ContentScanner, so the placement of the color setting operations may not be accurate, as PrimitiveFilter makes some assumptions on the current scanner cursor position).
      In the meantime, I have already enhanced the library to overcome such limitation: for the purpose, I have prepared a working sample that I'll include in the next release (0.0.8); in the next days I'll send it to this forum as a demonstrative anticipation.

      Stay tuned!

    • Here's the ColorEditSample; as I explained in my previous post, it's intended to work with the next release (0.0.8).

      Thank you

      // BEGIN ColorEditSample
      package it.stefanochizzolini.clown.samples;

      import it.stefanochizzolini.clown.documents.Document;
      import it.stefanochizzolini.clown.documents.Page;
      import it.stefanochizzolini.clown.documents.contents.Contents;
      import it.stefanochizzolini.clown.documents.contents.ContentScanner;
      import it.stefanochizzolini.clown.documents.contents.colorSpaces.Color;
      import it.stefanochizzolini.clown.documents.contents.colorSpaces.DeviceRGBColor;
      import it.stefanochizzolini.clown.documents.contents.composition.PrimitiveFilter;
      import it.stefanochizzolini.clown.documents.contents.objects.CompositeObject;
      import it.stefanochizzolini.clown.documents.contents.objects.ContentObject;
      import it.stefanochizzolini.clown.documents.contents.objects.Operation;
      import it.stefanochizzolini.clown.documents.contents.objects.SetFillColor;
      import it.stefanochizzolini.clown.documents.contents.objects.SetLineWidth;
      import it.stefanochizzolini.clown.documents.contents.objects.Text;
      import it.stefanochizzolini.clown.files.File;

      import java.util.List;

        This sample demonstrates how to alter the graphic contents (in this case: the text color)
        of pages within a PDF document.
        <p>This implementation is just a humble exercise: see the API documentation
        to perform all the possible access functionalities.</p>

        @author Stefano Chizzolini (
        @version 0.0.8
        @since 0.0.8
      public class ColorEditSample
        implements ISample
        public void run(
          SampleLoader loader
          File file;
            // (boilerplate user choice -- ignore it)
            String filePath = loader.getPdfFileChoice("Please select a PDF file");

            // 1. Open the PDF file!
            try{file = new File(filePath);}
            catch(Exception e){throw new RuntimeException(filePath + " file access error.",e);}

          // 2. Parsing the document...
          // Get the PDF document!
          Document document = file.getDocument();
          // Iterating through the pages...
          for(Page page : document.getPages())
            // Get the page contents!
            Contents contents = page.getContents();

            // Change the text color!
              new ContentScanner(contents), // Contents are wrapped within a content scanner in order to trace their graphics state changes.
              new DeviceRGBColor(1,0,0) // New text color to apply.

            // Update the page contents!

          // (boilerplate metadata insertion -- ignore it)
          loader.buildAccessories(document,this.getClass(),"Content tweaking (text color change)","changing text color inside existing pages");

          // 3. Serialize the PDF file (again, boilerplate code -- see the PDFClownSampleLoader class source code)!

        private void changeTextColor(
          ContentScanner scanner,
          Color newTextColor
          // Looking for text objects to ensure that they are shown using the proper color...
            NOTE: Page contents are represented by a sequence of content objects,
            possibly nested at multiple levels.
          PrimitiveFilter builder = new PrimitiveFilter(scanner);
          ContentObject object;
          while((object = scanner.getCurrent()) != null)
            if(object instanceof Text)
                NOTE: Text objects host an inner collection of content objects.
              ContentScanner textScanner = scanner.getChildLevel();
              builder.setScanner(textScanner); // Ensures that the builder inserts new content (in this case: SetFillColor operations) at the current scanning position.
              while(textScanner.getCurrent() != null)

            else if(object instanceof CompositeObject)
              // Scan the inner level!
                NOTE: Composite objects host an inner collection of content objects.

      // END ColorEditSample