我使用PDF BOX获取PDF格式的文本颜色信息。我可以使用以下代码获取输出。但我怀疑StrokingColor代表什么,非抚摸颜色代表什么。基于此,我将如何决定哪个文本具有哪种颜色。有人建议我吗?我的cuurent输出是这样的:DeviceRGB DeviceCMYK java.awt.Color中[R = 63,G = 240,B = 0] java.awt.Color中[R = 35,G = 31,B = 32] 34.934998 31.11 31.875
PDDocument doc = null;
try {
doc = PDDocument.load(strFilepath);
PDFStreamEngine engine = new PDFStreamEngine(ResourceLoader.loadProperties("org/apache/pdfbox/resources/PageDrawer.properties"));
PDPage page = (PDPage)doc.getDocumentCatalog().getAllPages().get(1);
engine.processStream(page, page.findResources(), page.getContents().getStream());
PDGraphicsState graphicState = engine.getGraphicsState();
System.out.println(graphicState.getStrokingColor().getColorSpace().getName());
System.out.println(graphicState.getNonStrokingColor().getColorSpace().getName());
System.out.println(graphicState.getNonStrokingColor().getJavaColor());
System.out.println(graphicState.getStrokingColor().getJavaColor());
float colorSpaceValues[] = graphicState.getStrokingColor().getColorSpaceValue();
for (float c : colorSpaceValues) {
System.out.println(c * 255);
}
}
finally {
if (doc != null) {
doc.close();
}
}
答案 0 :(得分:5)
根据评论中的澄清,OP希望
将一个pdf页面的字体颜色与另一个pdf页面进行比较[...]如果有一个黑色的文本“Sample”和一些灰色的其他文本“sample1”....我需要知道样品 - >黑色,sample1 - >像这样的灰色......我想要全文及其颜色
PDFBox有一个文本提取引擎PDFTextStripper
。然而,将它用于手头的任务存在一些挑战:
最初不设计用于在文本旁边提取颜色信息;它使用的TextPosition
对象甚至没有任何颜色属性。因此,我们将不得不进行一些扩展。
我们将首先注册颜色操作的监听器,以便跟踪颜色。
我们还会将TextPosition
对象的颜色信息存储在另一个结构中(我更愿意相应地扩展文本位置,但由于几个难以访问的私有成员,这意味着相当麻烦)。 / p>
这已在this answer中详细显示;对于背景,请看那里。
PDF允许多种绘制文字的方式。字母可以用一种颜色填充,其边界可以用另一种颜色填充。它们的边界甚至可以作为后续绘图操作的剪切路径。我们只考虑填充和抚摸颜色。
以后绘制的文字可能被其他图纸覆盖,要么完全隐藏它,要么改变其外观颜色。我们暂时不理会这一点。
如上所述,我们像这样扩展PDFTextStripper
:
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.pdfbox.util.PDFTextStripper;
import org.apache.pdfbox.util.TextPosition;
public class ColorTextStripper extends PDFTextStripper
{
public ColorTextStripper() throws IOException
{
super();
setSuppressDuplicateOverlappingText(false);
registerOperatorProcessor("CS", new org.apache.pdfbox.util.operator.SetStrokingColorSpace());
registerOperatorProcessor("cs", new org.apache.pdfbox.util.operator.SetNonStrokingColorSpace());
registerOperatorProcessor("SC", new org.apache.pdfbox.util.operator.SetStrokingColor());
registerOperatorProcessor("sc", new org.apache.pdfbox.util.operator.SetNonStrokingColor());
registerOperatorProcessor("SCN", new org.apache.pdfbox.util.operator.SetStrokingColor());
registerOperatorProcessor("scn", new org.apache.pdfbox.util.operator.SetNonStrokingColor());
registerOperatorProcessor("G", new org.apache.pdfbox.util.operator.SetStrokingGrayColor());
registerOperatorProcessor("g", new org.apache.pdfbox.util.operator.SetNonStrokingGrayColor());
registerOperatorProcessor("RG", new org.apache.pdfbox.util.operator.SetStrokingRGBColor());
registerOperatorProcessor("rg", new org.apache.pdfbox.util.operator.SetNonStrokingRGBColor());
registerOperatorProcessor("K", new org.apache.pdfbox.util.operator.SetStrokingCMYKColor());
registerOperatorProcessor("k", new org.apache.pdfbox.util.operator.SetNonStrokingCMYKColor());
}
@Override
protected void processTextPosition(TextPosition text)
{
renderingMode.put(text, getGraphicsState().getTextState().getRenderingMode());
strokingColor.put(text, getGraphicsState().getStrokingColor().getColorSpaceValue());
nonStrokingColor.put(text, getGraphicsState().getNonStrokingColor().getColorSpaceValue());
super.processTextPosition(text);
}
Map<TextPosition, Integer> renderingMode = new HashMap<TextPosition, Integer>();
Map<TextPosition, float[]> strokingColor = new HashMap<TextPosition, float[]>();
Map<TextPosition, float[]> nonStrokingColor = new HashMap<TextPosition, float[]>();
final static List<Integer> FILLING_MODES = Arrays.asList(0, 2, 4, 6);
final static List<Integer> STROKING_MODES = Arrays.asList(1, 2, 5, 6);
final static List<Integer> CLIPPING_MODES = Arrays.asList(4, 5, 6, 7);
@Override
protected void writeString(String text, List<TextPosition> textPositions) throws IOException
{
for (TextPosition textPosition: textPositions)
{
Integer charRenderingMode = renderingMode.get(textPosition);
float[] charStrokingColor = strokingColor.get(textPosition);
float[] charNonStrokingColor = nonStrokingColor.get(textPosition);
StringBuilder textBuilder = new StringBuilder();
textBuilder.append(textPosition.getCharacter())
.append("{");
if (FILLING_MODES.contains(charRenderingMode))
{
textBuilder.append("FILL:")
.append(toString(charNonStrokingColor))
.append(';');
}
if (STROKING_MODES.contains(charRenderingMode))
{
textBuilder.append("STROKE:")
.append(toString(charStrokingColor))
.append(';');
}
if (CLIPPING_MODES.contains(charRenderingMode))
{
textBuilder.append("CLIP;");
}
textBuilder.append("}");
writeString(textBuilder.toString());
}
}
String toString(float[] values)
{
if (values == null)
return "null";
StringBuilder builder = new StringBuilder();
switch(values.length)
{
case 1:
builder.append("GRAY"); break;
case 3:
builder.append("RGB"); break;
case 4:
builder.append("CMYK"); break;
default:
builder.append("UNKNOWN");
}
for (float f: values)
{
builder.append(' ')
.append(f);
}
return builder.toString();
}
}
您可以这样称呼它:
PDFTextStripper stripper = new ColorTextStripper();
PDDocument document = PDDocument.load(SOURCE_FILE);
String text = stripper.getText(document);
结果文本包含以下内容:
P{FILL:RGB 0.803 0.076 0.086;}e{FILL:RGB 0.803 0.076 0.086;}l{FILL:RGB 0.803 0.076 0.086;}l{FILL:RGB 0.803 0.076 0.086;}e{FILL:RGB 0.803 0.076 0.086;}
和
G{FILL:RGB 0.102 0.101 0.095;}r{FILL:RGB 0.102 0.101 0.095;}a{FILL:RGB 0.102 0.101 0.095;}z{FILL:RGB 0.102 0.101 0.095;}i{FILL:RGB 0.102 0.101 0.095;}e{FILL:RGB 0.102 0.101 0.095;}
Pelle 和 Grazie 来自
或
K{FILL:RGB 0.0 0.322 0.573;}E{FILL:RGB 0.0 0.322 0.573;}Y{FILL:RGB 0.0 0.322 0.573;}
和
C{FILL:GRAY 0.0;}o{FILL:GRAY 0.0;}m{FILL:GRAY 0.0;}b{FILL:GRAY 0.0;}i{FILL:GRAY 0.0;}n{FILL:GRAY 0.0;}e{FILL:GRAY 0.0;}d{FILL:GRAY 0.0;}
KEY 和 Combined 来自:
您可以创建一些以结构化方式同时包含颜色和字符信息的类,而不是将所有信息序列化为String
结果。就像现在在writeString
中创建String结果一样,您可以更改此方法以将此类的实例添加到其中的某个列表中。
至少需要PDFBox版本1.8.4才能完成这项工作。我使用2.0.0-SNAPSHOT测试它,但1.8.4就足够了。另一方面,1.8.3有一个错误,有时会将错误的TextPosition
个对象转发给writeString
,参见PDFBOX-1804,早期版本根本不向TextPosition
提供writeString
集合。