替换 PDF 文件中的黑色
Replace black color in PDF file
我正在尝试替换 PDF 文件中的黑色 (0,0,0) 颜色(它不是带有名称的专色,它是正常的填充颜色)但我还找不到方法来做到这一点, 谁能帮我解决这个问题?
附上 PDF 文件:https://gofile.io/d/AB1Bil
利用 PdfContentStreamEditor
from ,您可以像这样替换页面内容流中选择黑色 RGB 颜色的指令:
float[] replacementColor = new float[] {.1f, .7f, .6f};
PDDocument document = ...;
for (PDPage page : document.getDocumentCatalog().getPages()) {
PdfContentStreamEditor identity = new PdfContentStreamEditor(document, page) {
@Override
protected void write(ContentStreamWriter contentStreamWriter, Operator operator, List<COSBase> operands) throws IOException {
String operatorString = operator.getName();
if (RGB_FILL_COLOR_OPERATORS.contains(operatorString))
{
if (operands.size() == 3) {
if (isApproximately(operands.get(0), 0) &&
isApproximately(operands.get(1), 0) &&
isApproximately(operands.get(2), 0)) {
for (int i = 0; i < replacementColor.length; i++) {
operands.set(i, new COSFloat(replacementColor[i]));
}
}
}
}
super.write(contentStreamWriter, operator, operands);
}
boolean isApproximately(COSBase number, float compare) {
return (number instanceof COSNumber) && Math.abs(((COSNumber)number).floatValue() - compare) < 1e-4;
}
final List<String> RGB_FILL_COLOR_OPERATORS = Arrays.asList("rg", "sc", "scn");
};
identity.processPage(page);
}
document.save("gridShapesModified-RGBBlackReplaced.pdf");
(EditPageContent 测试 testReplaceRGBBlackGridShapesModified
)
当然,对于您的示例 PDF,可以简单地采用内容流并将 0 0 0 rg
替换为 .1 .7 .6 rg
以获得相同的效果。但一般情况下,情况可能会更复杂,所以我建议采用这种方法。
不过要注意:
- 内容流编辑器只操作即时页面内容流。但是也可以在 XObjects 中设置和使用颜色以及从那里使用的模式。所以严格来说,必须深入到页面资源中的 XObjects 和模式。
- 我盲目地把所有的三参数
sc
和scn
操作都当成设置RGB颜色了。事实上,它们还可以参考 Lab 颜色和(对于 scn
)图案、分离、DeviceN 和 ICCBased 颜色。严格来说应该在这里测试当前的非描边色彩空间。
- 我完全忽略了使用有趣的混合模式在其他内容上添加的内容可能会导致显示颜色与当前填充颜色不同。
我正在尝试替换 PDF 文件中的黑色 (0,0,0) 颜色(它不是带有名称的专色,它是正常的填充颜色)但我还找不到方法来做到这一点, 谁能帮我解决这个问题?
附上 PDF 文件:https://gofile.io/d/AB1Bil
利用 PdfContentStreamEditor
from
float[] replacementColor = new float[] {.1f, .7f, .6f};
PDDocument document = ...;
for (PDPage page : document.getDocumentCatalog().getPages()) {
PdfContentStreamEditor identity = new PdfContentStreamEditor(document, page) {
@Override
protected void write(ContentStreamWriter contentStreamWriter, Operator operator, List<COSBase> operands) throws IOException {
String operatorString = operator.getName();
if (RGB_FILL_COLOR_OPERATORS.contains(operatorString))
{
if (operands.size() == 3) {
if (isApproximately(operands.get(0), 0) &&
isApproximately(operands.get(1), 0) &&
isApproximately(operands.get(2), 0)) {
for (int i = 0; i < replacementColor.length; i++) {
operands.set(i, new COSFloat(replacementColor[i]));
}
}
}
}
super.write(contentStreamWriter, operator, operands);
}
boolean isApproximately(COSBase number, float compare) {
return (number instanceof COSNumber) && Math.abs(((COSNumber)number).floatValue() - compare) < 1e-4;
}
final List<String> RGB_FILL_COLOR_OPERATORS = Arrays.asList("rg", "sc", "scn");
};
identity.processPage(page);
}
document.save("gridShapesModified-RGBBlackReplaced.pdf");
(EditPageContent 测试 testReplaceRGBBlackGridShapesModified
)
当然,对于您的示例 PDF,可以简单地采用内容流并将 0 0 0 rg
替换为 .1 .7 .6 rg
以获得相同的效果。但一般情况下,情况可能会更复杂,所以我建议采用这种方法。
不过要注意:
- 内容流编辑器只操作即时页面内容流。但是也可以在 XObjects 中设置和使用颜色以及从那里使用的模式。所以严格来说,必须深入到页面资源中的 XObjects 和模式。
- 我盲目地把所有的三参数
sc
和scn
操作都当成设置RGB颜色了。事实上,它们还可以参考 Lab 颜色和(对于scn
)图案、分离、DeviceN 和 ICCBased 颜色。严格来说应该在这里测试当前的非描边色彩空间。 - 我完全忽略了使用有趣的混合模式在其他内容上添加的内容可能会导致显示颜色与当前填充颜色不同。