【问题标题】:PDFBox tint transformation of PDF page contents (colors)PDF 页面内容的 PDFBox 色调转换(颜色)
【发布时间】:2021-01-11 10:53:15
【问题描述】:

我正在对采用 RGB 颜色(tintR、tintG、tintB、tintAlpha)的 PNG 和 JPG 图像使用色调转换,然后循环附加图像的像素并将每个像素值更改为

newR = pixelR * (tintR / 255)

newG、newB 和 newAlpha 相同

它工作正常,有没有办法对 PDF 页面内容(颜色)做同样的操作?

谢谢

【问题讨论】:

  • 您可能想要使用 PDF 传输函数,参见。 ISO 32000-1 第 10.4 节。
  • 你能给我一个例子或一些可以帮助我的代码吗?

标签: java pdfbox tint


【解决方案1】:

您可以尝试通过传递函数实现类似的功能(参见 ISO 32000-1 第 10.4 节)。

产生的效果例如可以是这样的(左上角是原始内容):

这是使用以下代码创建的

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 测试testSimpleTransferExample)

使用这些辅助方法:

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);
}

(来自ApplyTransferFunction 的辅助方法)

因此,

有没有办法对 PDF 页面内容(颜色)做同样的操作?

是的,只需在页面内容的开头应用您选择的传递函数,即将它添加到您使用 AppendMode.PREPEND 为页面创建的 PDPageContentStream 中。

【讨论】:

    猜你喜欢
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-16
    • 2015-02-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多