Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
228 views
in Technique[技术] by (71.8m points)

java - PDFBox tint transformation of PDF page contents (colors)

I'm using tint transformation for PNG and JPG images that take an RGB color (tintR, tintG, tintB, tintAlpha) and then I loop on the pixels of the attached image and change each pixel value by

newR = pixelR * (tintR / 255)

same for newG, newB and newAlpha

It's working correctly, is there a way to do the same operation on PDFpage contents(colors)?

Thanks


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can try and achieve something similar by means of transfer functions (see ISO 32000-1 section 10.4).

Resulting effects can for example be like this (top left is the original content):

screen shot

This has been created using the following code

try (PDDocument pdDocument = new PDDocument()) {
    PDPage pdPage = new PDPage();
    pdDocument.addPage(pdPage);

    PDImageXObject pdImage = [... create  image XObject ...];

    try (PDPageContentStream canvas = new PDPageContentStream(pdDocument, pdPage)) {
        canvas.drawImage(pdImage, 0, 600, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ neg 1 add }"));
        canvas.drawImage(pdImage, 150, 600, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ 90 mul cos }"));
        canvas.drawImage(pdImage, 300, 600, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ 90 mul sin neg 1 add }"));
        canvas.drawImage(pdImage, 450, 600, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ .5 mul }"));
        canvas.drawImage(pdImage, 0, 450, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ 90 mul cos neg 1 add }"));
        canvas.drawImage(pdImage, 150, 450, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ 90 mul sin }"));
        canvas.drawImage(pdImage, 300, 450, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ .5 mul .5 add }"));
        canvas.drawImage(pdImage, 450, 450, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ }", "{ pop 1 }", "{ pop 1 }", "{ pop 1 }"));
        canvas.drawImage(pdImage, 0, 300, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ pop 1 }", "{ }", "{ pop 1 }", "{ pop 1 }"));
        canvas.drawImage(pdImage, 150, 300, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ pop 1 }", "{ pop 1 }", "{ }", "{ pop 1 }"));
        canvas.drawImage(pdImage, 300, 300, 150, 150);
        canvas.setGraphicsStateParameters(createTransferedState("{ pop 1 }", "{ pop 1 }", "{ pop 1 }", "{ }"));
        canvas.drawImage(pdImage, 450, 300, 150, 150);
    }

    pdDocument.save("SimpleTransferExample.pdf");
}

(ApplyTransferFunction test testSimpleTransferExample)

using these helper methods:

PDExtendedGraphicsState createTransferedState(String function) throws IOException {
    PDExtendedGraphicsState transferedState = new PDExtendedGraphicsState();
    transferedState.setTransfer(createTransferFunction(function).getCOSObject());
    return transferedState;
}

PDExtendedGraphicsState createTransferedState(String function1, String function2, String function3, String function4) throws IOException {
    COSArray array = new COSArray();
    array.add(createTransferFunction(function1).getCOSObject());
    array.add(createTransferFunction(function2).getCOSObject());
    array.add(createTransferFunction(function3).getCOSObject());
    array.add(createTransferFunction(function4).getCOSObject());
    PDExtendedGraphicsState transferedState = new PDExtendedGraphicsState();
    transferedState.setTransfer(array);
    return transferedState;
}

PDFunctionType4 createTransferFunction(String function) throws IOException {
    return createFunction(function, new float[] {0f, 1.0f}, new float[] {0f, 1.0f});
}

/** @see org.apache.pdfbox.pdmodel.common.function.TestPDFunctionType4 */
PDFunctionType4 createFunction(String function, float[] domain, float[] range) throws IOException {
    COSStream stream = new COSStream();
    stream.setInt("FunctionType", 4);
    COSArray domainArray = new COSArray();
    domainArray.setFloatArray(domain);
    stream.setItem("Domain", domainArray);
    COSArray rangeArray = new COSArray();
    rangeArray.setFloatArray(range);
    stream.setItem("Range", rangeArray);
    
    try (OutputStream out = stream.createOutputStream()) {
        byte[] data = function.getBytes(StandardCharsets.US_ASCII);
        out.write(data, 0, data.length);
    }

    return new PDFunctionType4(stream);
}

(helper methods from ApplyTransferFunction)

Thus,

is there a way to do the same operation on PDFpage contents(colors)?

yes, simply apply the transfer function of your choice at the beginning of the page content, i.e. add it in a PDPageContentStream you create for the page using AppendMode.PREPEND.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...