我想让现有PDF中的所有文字都透明。
选项1:选择所有文本,找到颜色属性并将其更改为“无色”
或者,如果没有这样的财产
选项2:解析页面内容Stream和该页面的所有Form XObjects,检测文本块(BT
/ ET
),并将渲染模式设置为invisble。
这似乎是一项复杂的操作。
这是我的example file
以下代码生成PDF(示例pdf文件):
Document document = new Document(new Rectangle(width, height));
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
document.open();
PdfContentByte picCanvas = null;
PdfContentByte txtCanvas = null;
if (isUnderPic) {
txtCanvas = writer.getDirectContentUnder();
picCanvas = writer.getDirectContent();
} else {
txtCanvas = writer.getDirectContent();
picCanvas = writer.getDirectContentUnder();
}
BaseFont bf = null;
if (null != pageList) {
int[] dpi = { 0, 0 };
if (dpiType == 1) {
dpi[0] = 300;
dpi[1] = 300;
} else if (dpiType == 2) {
dpi[0] = 600;
dpi[1] = 600;
}
for (int i = 0; i < pageList.size(); i++) {
PDFPage page = pageList.get(i);
Image pageImage = null;
if (pdfType == 3) {
pageImage = Image.getInstance(page.getBinImage());
} else {
pageImage = Image.getInstance(page.getOriImage());
}
if (pageImage.getWidth() > 0) {
pageImage.scaleAbsolute(page.getWidth(), page.getHeight());
}
pageImage.setAbsolutePosition(0, 0);
picCanvas.addImage(pageImage);
if (pdfType == 2 || pdfType == 3) {
for (PageElement ele : page.getElementList()) {
if (ele.getType().equals(PDFConstant.ElementType.PDF_ELEMENT_CHAR)) {
txtCanvas.beginText();
if (isColor) {
txtCanvas.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
txtCanvas.setColorFill(BaseColor.RED);
} else {
txtCanvas.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_INVISIBLE);
}
String font = ele.getFont();
try {
bf = fonts.get(font);
if (null == bf) {
bf = BaseFont.createFont(font, "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
fonts.put(font, bf);
}
} catch (Exception e) {
bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
fonts.put(font, bf);
}
txtCanvas.setFontAndSize(bf, ele.getFontSize());
txtCanvas.setTextMatrix(ele.getPageX(), ele.getPageY(page.getRcInPage()));
txtCanvas.showText(ele.getCode());
txtCanvas.endText();
}
}
}
if (StringUtils.isNotBlank(cutPath)) {
for (PageElement ele : page.getElementList()) {
if (ele.getType().equals(PDFConstant.ElementType.PDF_ELEMENT_PIC) && StringUtils.isNotBlank(ele.getCutPicSrc())) {
ImageTools.cutPic(ele.getRcInImage(), page.getOriImage(), ele.getCutPicSrc(), dpi);
}
}
}
if (pdfType == 3) {
logger.debug("pdfType == 3");
for (PageElement ele : page.getElementList()) {
if (ele.getType().equals(PDFConstant.ElementType.PDF_ELEMENT_PIC) && StringUtils.isNotBlank(ele.getCutPicSrc())) {
if (new File(ele.getCutPicSrc()).exists()) {
Image cutCover = Image.getInstance(ImageTools.drawImage((int) ele.getWidth(), (int) ele.getHeight()));
if (cutCover.getWidth() > 0) {
cutCover.scaleAbsolute(ele.getWidth(), ele.getHeight());
}
cutCover.setAbsolutePosition(ele.getPageX(), ele.getPageY(page.getRcInPage()));
picCanvas.addImage(cutCover);
Image pic = Image.getInstance(ele.getCutPicSrc());
if (pic.getWidth() > 0) {
pic.scaleAbsolute(ele.getWidth(), ele.getHeight());
}
pic.setAbsolutePosition(ele.getPageX(), ele.getPageY(page.getRcInPage()));
picCanvas.addImage(pic);
}
}
}
}
if (i + 1 < pageList.size()) {
document.setPageSize(new Rectangle(pageList.get(i + 1).getWidth(), pageList.get(i + 1).getHeight()));
} else {
document.setPageSize(new Rectangle(pageList.get(i).getWidth(), pageList.get(i).getHeight()));
}
document.newPage();
}
}
document.close();
答案 0 :(得分:2)
我看过你的PDF,我发现PDF是扫描图像。文本不是真正的文本:它由图像组成。您的问题无效,因为它假定文本由矢量数据组成(使用PDF语法定义,例如BT
和ET
)。实际上,文本是一堆像素,任何像素都不知道它是属于文本字形还是图像。简而言之:你使用了错误的方法。您正在尝试使用PDF软件解决问题,而您应该使用操作光栅图像的工具。
这是我从PDF中提取的图像:
OP宣称有两层:一层有图像,一层有文字。这可能是真的,但图像也包含光栅化文本,并且无法通过更改PDF语法从图像中删除该文本。
如果您知道坐标,您可以覆盖文本,但这在很大程度上取决于OCR操作的准确性。
如果您的要求不是覆盖图像中的文本,而是覆盖矢量图层的文本,则添加在添加矢量文本的语法之后添加图像的语法就足够了。如果图像不透明,它将覆盖所有文本。这是在RepeatImage
示例中完成的:
PdfReader reader = new PdfReader(src);
// We assume that there's a single large picture on the first page
PdfDictionary page = reader.getPageN(1);
PdfDictionary resources = page.getAsDict(PdfName.RESOURCES);
PdfDictionary xobjects = resources.getAsDict(PdfName.XOBJECT);
PdfName imgName = xobjects.getKeys().iterator().next();
Image img = Image.getInstance((PRIndirectReference)xobjects.getAsIndirectObject(imgName));
img.setAbsolutePosition(0, 0);
img.scaleAbsolute(reader.getPageSize(1));
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.getOverContent(1).addImage(img);
stamper.close();
reader.close();
看看resulting PDF;现在你仍然可以选择矢量文本,但它不再可见。