我使用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(); } }
mkl.. 5
根据OP希望的评论中的澄清
比较一个pdf页面的字体颜色与另一个pdf页面[...]如果有一个黑色的文本"Sample"和一些灰色的其他文本"sample1"....我需要知道样本 - >黑色,样本1 - >灰色这样......我想要全文及其颜色
PDFBox有一个文本提取引擎,PDFTextStripper
.将它用于手头的任务有一些挑战,其中包括:
最初它不是为了在文本旁边提取颜色信息而设计的; TextPosition
它使用的对象甚至没有任何颜色属性.因此,我们将不得不对其进行一些扩展.
我们将首先注册颜色操作的监听器,以便跟踪颜色.
我们还会将TextPosition
对象的颜色信息存储在另一个结构中(我宁愿相应地扩展文本位置,但由于几个难以访问的私有成员,这意味着相当麻烦).
这已经在这个答案中详细说明了; 对于背景,看那里.
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 renderingMode = new HashMap();
Map strokingColor = new HashMap();
Map nonStrokingColor = new HashMap();
final static List FILLING_MODES = Arrays.asList(0, 2, 4, 6);
final static List STROKING_MODES = Arrays.asList(1, 2, 5, 6);
final static List CLIPPING_MODES = Arrays.asList(4, 5, 6, 7);
@Override
protected void writeString(String text, List 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;}
对于佩尔和感恩教堂从这个
要么
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和由此组合:
String
您可以创建一些以结构化方式同时包含颜色和字符信息的类,而不是将所有信息序列化为结果.就像现在创建String结果一样writeString
,您可以更改此方法以将此类的实例添加到其中的某个列表中.
至少需要PDFBox版本1.8.4才能完成这项工作.我使用2.0.0-SNAPSHOT测试它,但1.8.4就足够了.另一方面,1.8.3有一个错误,有时会转发错误的TextPosition
对象writeString
,参见 PDFBOX-1804和早期版本根本不提供TextPosition
集合writeString
.
根据OP希望的评论中的澄清
比较一个pdf页面的字体颜色与另一个pdf页面[...]如果有一个黑色的文本"Sample"和一些灰色的其他文本"sample1"....我需要知道样本 - >黑色,样本1 - >灰色这样......我想要全文及其颜色
PDFBox有一个文本提取引擎,PDFTextStripper
.将它用于手头的任务有一些挑战,其中包括:
最初它不是为了在文本旁边提取颜色信息而设计的; TextPosition
它使用的对象甚至没有任何颜色属性.因此,我们将不得不对其进行一些扩展.
我们将首先注册颜色操作的监听器,以便跟踪颜色.
我们还会将TextPosition
对象的颜色信息存储在另一个结构中(我宁愿相应地扩展文本位置,但由于几个难以访问的私有成员,这意味着相当麻烦).
这已经在这个答案中详细说明了; 对于背景,看那里.
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;}
对于佩尔和感恩教堂从这个
要么
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和由此组合:
String
您可以创建一些以结构化方式同时包含颜色和字符信息的类,而不是将所有信息序列化为结果.就像现在创建String结果一样writeString
,您可以更改此方法以将此类的实例添加到其中的某个列表中.
至少需要PDFBox版本1.8.4才能完成这项工作.我使用2.0.0-SNAPSHOT测试它,但1.8.4就足够了.另一方面,1.8.3有一个错误,有时会转发错误的TextPosition
对象writeString
,参见 PDFBOX-1804和早期版本根本不提供TextPosition
集合writeString
.