Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Oh, great and mystical Perl Monks, I am attempting to change the opacity of objects and images in a PDF and am experiencing great difficulty and pulling of hair in searching for documentation.

It seems that I must create an extended graphics state, but my addled brain cannot seem to grasp the method.

Any help or direction would be greatly appreciated.

Thanks in advance.

Replies are listed 'Best First'.
Re: PDF::API2 and opacity
by Neighbour (Friar) on Jun 08, 2010 at 10:29 UTC

    Once upon a time I had the same problem, which I then put away for 'later', but your request made me look it up.

    The method for it is actually quite simple, however due to the level of documentation for PDF::API2, nobody knows how :)

    Let's start by creating the document, add an A4-page, create text and gfxhandlers and add a font:
    my $pdf = PDF::API2->new( -file => "Test.pdf" ); my $page1 = $pdf->page; $page1->mediabox (210/mm, 297/mm); my $gfx = $page1->gfx; my $text = $page1->text; my %fonts = ( Helvetica => { Roman => $pdf->corefont( 'Helvetica', -encoding => 'latin1' ), } );
    Then we'll make some Extended Graphics states...One for everything we want transparent, and one for the non-transparent states.
    my $EGTransparent = $pdf->egstate(); my $EGNormal = $pdf->egstate(); $EGTransparent->transparency(0.5); $EGNormal->transparency(0);
    Suppose we now want to write some transparent text:
    $text->egstate($EGTransparent); $text->font($fonts{Helvetica}{Roman}, 16/pt); $text->translate(31/mm,250/mm); $text->text("This is a Test, just so you know", undef); $text->egstate($EGNormal);
    And add a transparent image to write transparent text over:
    $gfx->egstate($EGTransparent); $gfx->image($pdf->image_tiff("Image.tif"), 1/mm, 148/mm, 137/mm, 137/m +m); $gfx->egstate($EGNormal);
    And then add some non-transparent text, to show the difference:
    $text->translate(31/mm,200/mm); $text->text("This is a Test, just so you know", undef);
    And save our result...of course :)
    $pdf->save;
    All done.

      Neighbour, thanks for your code! It's close to what I'm searching and maybe this will help me to get to what I want to accomplish! But maybe you can help me directly, too:

      I'm trying to import an existing PDF page from file into a new PDF that is just beeing created with PDF::API2. I need to set the attribute "overprint" so the text above is printed over the background (without this attribute/option, the background is not printed behind the text so some printers leave white lines when printing the black ink).

      The module ExtGState, Extended Graphics states, seems to have methods for this attribute, but I don't know how to say they have to be applied to the background image. Any suggestions?

        I'm not entirely sure I understand what your problem is, but here is some code I use to make a "Test"-copy of a given PDF:
        sub PrintTextAngle { my ($texthandler, $x, $y, $rot, $text, $options) = @_; $texthandler->transform('-translate'=> [6/mm+$x/mm,10/mm+$y/mm], ' +-rotate'=>$rot); $texthandler->text($text, $options); } my $pdf_input = PDF::API2->open("$Filename"); foreach my $pagenr (1..$pdf_input->pages) { my $page = $pdf_input->openpage($pagenr); my $texthandler = $page->text; my $font = $pdf_input->corefont( 'Helvetica-Bold', -encode => ' +latin1' ); $texthandler->fillcolor('grey'); $texthandler->font($font, 256/pt); PrintTextAngle($texthandler, 50, 60, 45, "TEST"); $texthandler->font($font, 56/pt); PrintTextAngle($texthandler, 20, 10, 0, "Do not throw away!"); } $pdf_input->saveas("$Filename-TEST.pdf");
        This leaves the background (the imported PDF contents) intact and prints the text over this background (Though not semi-transparent, which you might want).

        If you still insist on toying with the overprint setting, use this:

        my $EGOverprint = $pdf->egstate(); my $EGNormal = $pdf->egstate(); $EGOverprint->strokeoverprint(1); $EGNormal->strokeoverprint(0);
        Before calling PrintTextAngle, set the Extended Graphics State using:
        $text->egstate($EGOverprint);
        Then print, and afterwards (if you want to print some more without using overprint) restore the Extended Graphics State with:
        $text->egstate($EGNormal);
Re: PDF::API2 and opacity
by sflitman (Hermit) on Jun 08, 2010 at 05:24 UTC
    Don't bother trying to do it natively in PDF, just make your image or text with desired opacity (or transparency) in a friendly environment like GD and export as PNG, then use PDF::API2::Resource::XObject::Image::PNG to import it into a PDF you are constructing. I have not tested this myself, but it is how I would go about solving the problem. If you are trying to alter existing objects in a PDF, that's another ball of wax. My guess there would be to extract them, modify them externally with a tool like GD or ImageMagick, then build a new output PDF.

    HTH,
    SSF

      May I send you my firstborn?