You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@pdfbox.apache.org by Adriaan Joubert <ad...@gmail.com> on 2014/07/15 20:44:24 UTC

Gradient paint

Hi,

I need to draw an axial gradient with PdfBox, but have not found an example
of how to do this. I'm using pdfbox 1.8.6.

I need to add a PDFunctionType2, but this always takes a dictionary - which
suggests that this is only implemented for reading documents?

I somehow need to create a PDShadingType2 so that I can initialise an
AxialShadingPaint.

Does anybody have a small example of how to draw a gradient, or give me any
idea of how to proceed?

Thanks,

Adriaan

Re: Gradient paint

Posted by Adriaan Joubert <ad...@gmail.com>.
Thanks a lot, Tilman. I'll have a go.

Cheers,

Adriaan


On 15 July 2014 22:07, Tilman Hausherr <TH...@t-online.de> wrote:

> It should be possible... You need to create a dictionary the hard way,
> with everything, and don't forget the function. It starts like this:
>
> COSDictionary dict = new COSDictionary();
>
> then you set the elements. It should not be too difficult, if you KNOW
> what an axial shading is. Here's a segment in postscript:
>
> <<
>    /ShadingType 2
>    /ColorSpace [ /DeviceRGB ]
>    /Coords [100 400 400 600 ]
>    /Function <<
>                /FunctionType 2
>                /Domain [ 0 1 ]
>                /C0 [ 1 0 0 ]
>                /C1 [ .5 1 .5 ]
>                /N 1
>              >>
> >>
>
> This is the same in PDF:
>
> 14 0 obj
> << /ColorSpace /DeviceRGB
>      /Coords [ 100 400 400 600 ]
>      /Function 15 0 R
>      /ShadingType 2 >>
> endobj
> 15 0 obj
> <<
> /C0 [ 1 0 0 ]
> /C1 [ 0.5 1 0.5 ]
> /Domain [ 0 1 ]
> /FunctionType 2
> /N 1 >>
> endobj
>
>
> So basically you have to set all these elements, note that coords is an
> array, and function is itself a dictionary again. Try it, and if it doesn't
> work, post your code here. Good luck!
>
> Tilman
>
>
>
>
>
> Am 15.07.2014 20:44, schrieb Adriaan Joubert:
>
>  Hi,
>>
>> I need to draw an axial gradient with PdfBox, but have not found an
>> example
>> of how to do this. I'm using pdfbox 1.8.6.
>>
>> I need to add a PDFunctionType2, but this always takes a dictionary -
>> which
>> suggests that this is only implemented for reading documents?
>>
>> I somehow need to create a PDShadingType2 so that I can initialise an
>> AxialShadingPaint.
>>
>> Does anybody have a small example of how to draw a gradient, or give me
>> any
>> idea of how to proceed?
>>
>> Thanks,
>>
>> Adriaan
>>
>>
>

Re: Gradient paint

Posted by Andreas Lehmkuehler <an...@lehmi.de>.
Hi,

just for convenience I'd prefer to use the setters (if available) instead of 
creating a dictionaries from scratch, e.g.

PDShadingType2 shading = new PDShadingType2(new COSDictionary());
shading.setShadingType(PDShading.SHADING_TYPE2);
shading.setColorSpace(PDDeviceRGB.INSTANCE);
.....


BR
Andreas Lehmkühler

Am 16.07.2014 06:42, schrieb Tilman Hausherr:
> For the 1.8 version the code is slightly different:
>
>
>              PDDocument document = new PDDocument();
>              PDPage page = new PDPage();
>              document.addPage(page);
>
>              // shading attributes
>              COSDictionary dict = new COSDictionary();
>              dict.setInt(COSName.SHADING_TYPE, 2);
>              dict.setName(COSName.COLORSPACE, "DeviceRGB");
>              COSArray coords = new COSArray();
>              coords.add(COSInteger.get(100));
>              coords.add(COSInteger.get(400));
>              coords.add(COSInteger.get(400));
>              coords.add(COSInteger.get(600));
>              dict.setItem(COSName.COORDS, coords);
>
>              // function with attributes
>              COSDictionary fdict = new COSDictionary();
>              fdict.setInt(COSName.FUNCTION_TYPE, 2);
>              COSArray domain = new COSArray();
>              domain.add(COSInteger.get(0));
>              domain.add(COSInteger.get(1));
>              COSArray c0 = new COSArray();
>              c0.add(COSFloat.get("1"));
>              c0.add(COSFloat.get("0"));
>              c0.add(COSFloat.get("0"));
>              COSArray c1 = new COSArray();
>              c1.add(COSFloat.get("0.5"));
>              c1.add(COSFloat.get("1"));
>              c1.add(COSFloat.get("0.5"));
>              fdict.setItem(COSName.DOMAIN, domain);
>              fdict.setItem(COSName.C0, c0);
>              fdict.setItem(COSName.C1, c1);
>              fdict.setInt(COSName.N, 1);
>              dict.setItem(COSName.FUNCTION, fdict);
>
>              PDShadingType2 shading = new PDShadingType2(dict);
>
>              // create and add to shading resources
>              page.setResources(new PDResources());
>              Map<String, PDShadingResources> shadings = new HashMap<String,
> PDShadingResources>();
>              shadings.put("sh1", (PDShadingResources) shading);
>              page.getResources().setShadings(shadings);
>
>              // invoke shading from content stream
>              PDPageContentStream contentStream = new
> PDPageContentStream(document, page, true, false);
>              contentStream.appendRawCommands("/sh1 sh");
>              contentStream.close();
>
>              document.save("shtest.pdf");
>              document.close();


Re: Gradient paint

Posted by Tilman Hausherr <TH...@t-online.de>.
For the 1.8 version the code is slightly different:


             PDDocument document = new PDDocument();
             PDPage page = new PDPage();
             document.addPage(page);

             // shading attributes
             COSDictionary dict = new COSDictionary();
             dict.setInt(COSName.SHADING_TYPE, 2);
             dict.setName(COSName.COLORSPACE, "DeviceRGB");
             COSArray coords = new COSArray();
             coords.add(COSInteger.get(100));
             coords.add(COSInteger.get(400));
             coords.add(COSInteger.get(400));
             coords.add(COSInteger.get(600));
             dict.setItem(COSName.COORDS, coords);

             // function with attributes
             COSDictionary fdict = new COSDictionary();
             fdict.setInt(COSName.FUNCTION_TYPE, 2);
             COSArray domain = new COSArray();
             domain.add(COSInteger.get(0));
             domain.add(COSInteger.get(1));
             COSArray c0 = new COSArray();
             c0.add(COSFloat.get("1"));
             c0.add(COSFloat.get("0"));
             c0.add(COSFloat.get("0"));
             COSArray c1 = new COSArray();
             c1.add(COSFloat.get("0.5"));
             c1.add(COSFloat.get("1"));
             c1.add(COSFloat.get("0.5"));
             fdict.setItem(COSName.DOMAIN, domain);
             fdict.setItem(COSName.C0, c0);
             fdict.setItem(COSName.C1, c1);
             fdict.setInt(COSName.N, 1);
             dict.setItem(COSName.FUNCTION, fdict);

             PDShadingType2 shading = new PDShadingType2(dict);

             // create and add to shading resources
             page.setResources(new PDResources());
             Map<String, PDShadingResources> shadings = new 
HashMap<String, PDShadingResources>();
             shadings.put("sh1", (PDShadingResources) shading);
             page.getResources().setShadings(shadings);

             // invoke shading from content stream
             PDPageContentStream contentStream = new 
PDPageContentStream(document, page, true, false);
             contentStream.appendRawCommands("/sh1 sh");
             contentStream.close();

             document.save("shtest.pdf");
             document.close();

Re: Gradient paint

Posted by Adriaan Joubert <ad...@gmail.com>.
Fantastic! I'll try this.

Much appreciated!

Adriaan


On 15 July 2014 23:19, Tilman Hausherr <TH...@t-online.de> wrote:

> I wanted to see whether it works (yes), here's some quick code:
>
>
>         PDDocument doc = new PDDocument();
>         PDPage page = new PDPage();
>         doc.addPage(page);
>         page.setResources(new PDResources());
>         System.out.println(page.getResources());
>         Map<String, PDShading> shadings = new HashMap<>();
>
>         COSDictionary dict = new COSDictionary();
>         dict.setInt(COSName.SHADING_TYPE, 2);
>         dict.setName(COSName.COLORSPACE, "DeviceRGB");
>         COSArray coords = new COSArray();
>         coords.add(COSInteger.get(100));
>         coords.add(COSInteger.get(400));
>         coords.add(COSInteger.get(400));
>         coords.add(COSInteger.get(600));
>         dict.setItem(COSName.COORDS, coords);
>
>         COSDictionary fdict = new COSDictionary();
>         fdict.setInt(COSName.FUNCTION_TYPE, 2);
>         COSArray dom = new COSArray();
>         dom.add(COSInteger.get(0));
>         dom.add(COSInteger.get(1));
>         COSArray c0 = new COSArray();
>         c0.add(COSFloat.get("1"));
>         c0.add(COSFloat.get("0"));
>         c0.add(COSFloat.get("0"));
>         COSArray c1 = new COSArray();
>         c1.add(COSFloat.get("0.5"));
>         c1.add(COSFloat.get("1"));
>         c1.add(COSFloat.get("0.5"));
>         fdict.setItem(COSName.DOMAIN, dom);
>         fdict.setItem(COSName.C0, c0);
>         fdict.setItem(COSName.C1, c1);
>         fdict.setInt(COSName.N, 1);
>         PDFunctionType2 fun = new PDFunctionType2(fdict);
>         dict.setItem(COSName.FUNCTION, fdict);
>         PDShadingType2 shading = new PDShadingType2(dict);
>         shadings.put("sh1", shading);
>         page.getResources().setShadings(shadings);
>         PDPageContentStream contentStream = new PDPageContentStream(doc,
> page, true, false);
>         contentStream.appendRawCommands("/sh1 sh");
>         contentStream.close();
>         doc.save("shtest.pdf");
>         doc.close();
>
>

Re: Gradient paint

Posted by Tilman Hausherr <TH...@t-online.de>.
I wanted to see whether it works (yes), here's some quick code:


         PDDocument doc = new PDDocument();
         PDPage page = new PDPage();
         doc.addPage(page);
         page.setResources(new PDResources());
         System.out.println(page.getResources());
         Map<String, PDShading> shadings = new HashMap<>();
         COSDictionary dict = new COSDictionary();
         dict.setInt(COSName.SHADING_TYPE, 2);
         dict.setName(COSName.COLORSPACE, "DeviceRGB");
         COSArray coords = new COSArray();
         coords.add(COSInteger.get(100));
         coords.add(COSInteger.get(400));
         coords.add(COSInteger.get(400));
         coords.add(COSInteger.get(600));
         dict.setItem(COSName.COORDS, coords);

         COSDictionary fdict = new COSDictionary();
         fdict.setInt(COSName.FUNCTION_TYPE, 2);
         COSArray dom = new COSArray();
         dom.add(COSInteger.get(0));
         dom.add(COSInteger.get(1));
         COSArray c0 = new COSArray();
         c0.add(COSFloat.get("1"));
         c0.add(COSFloat.get("0"));
         c0.add(COSFloat.get("0"));
         COSArray c1 = new COSArray();
         c1.add(COSFloat.get("0.5"));
         c1.add(COSFloat.get("1"));
         c1.add(COSFloat.get("0.5"));
         fdict.setItem(COSName.DOMAIN, dom);
         fdict.setItem(COSName.C0, c0);
         fdict.setItem(COSName.C1, c1);
         fdict.setInt(COSName.N, 1);
         PDFunctionType2 fun = new PDFunctionType2(fdict);
         dict.setItem(COSName.FUNCTION, fdict);
         PDShadingType2 shading = new PDShadingType2(dict);
         shadings.put("sh1", shading);
         page.getResources().setShadings(shadings);
         PDPageContentStream contentStream = new 
PDPageContentStream(doc, page, true, false);
         contentStream.appendRawCommands("/sh1 sh");
         contentStream.close();
         doc.save("shtest.pdf");
         doc.close();


Re: Gradient paint

Posted by Tilman Hausherr <TH...@t-online.de>.
It should be possible... You need to create a dictionary the hard way, 
with everything, and don't forget the function. It starts like this:

COSDictionary dict = new COSDictionary();

then you set the elements. It should not be too difficult, if you KNOW 
what an axial shading is. Here's a segment in postscript:

<<
    /ShadingType 2
    /ColorSpace [ /DeviceRGB ]
    /Coords [100 400 400 600 ]
    /Function <<
                /FunctionType 2
                /Domain [ 0 1 ]
                /C0 [ 1 0 0 ]
                /C1 [ .5 1 .5 ]
                /N 1
              >>
 >>

This is the same in PDF:

14 0 obj
<< /ColorSpace /DeviceRGB
      /Coords [ 100 400 400 600 ]
      /Function 15 0 R
      /ShadingType 2 >>
endobj
15 0 obj
<<
/C0 [ 1 0 0 ]
/C1 [ 0.5 1 0.5 ]
/Domain [ 0 1 ]
/FunctionType 2
/N 1 >>
endobj


So basically you have to set all these elements, note that coords is an 
array, and function is itself a dictionary again. Try it, and if it 
doesn't work, post your code here. Good luck!

Tilman





Am 15.07.2014 20:44, schrieb Adriaan Joubert:
> Hi,
>
> I need to draw an axial gradient with PdfBox, but have not found an example
> of how to do this. I'm using pdfbox 1.8.6.
>
> I need to add a PDFunctionType2, but this always takes a dictionary - which
> suggests that this is only implemented for reading documents?
>
> I somehow need to create a PDShadingType2 so that I can initialise an
> AxialShadingPaint.
>
> Does anybody have a small example of how to draw a gradient, or give me any
> idea of how to proceed?
>
> Thanks,
>
> Adriaan
>