这个程序适用于我创建的PDF文件,但我必须获得Stedman的Dictionary.pdf的粗体和斜体信息,这似乎有一个隐藏此信息的技巧。任何建议都将受到热烈欢迎。
注意: 这是一个纯粹的自愿努力,以帮助一些医生朋友。
package arspdfbox;
import java.io.*;
import org.apache.pdfbox.exceptions.InvalidPasswordException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.util.PDFTextStripper;
import org.apache.pdfbox.util.TextPosition;
import java.io.IOException;
import java.util.List;
public class PrintTextLocations extends PDFTextStripper {
public PrintTextLocations() throws IOException {
super.setSortByPosition(true);
}
public static void main(String[] args) throws Exception {
PDDocument document = null;
try {
File input = new File("Stedman_Medical_Dictionary.pdf");
//File input = new File("results/FontExample5.pdf");
document = PDDocument.load(input);
if (document.isEncrypted()) {
try {
document.decrypt("");
} catch (InvalidPasswordException e) {
System.err.println("Error: Document is encrypted with a password.");
System.exit(1);
}
}
PrintTextLocations printer = new PrintTextLocations();
List allPages = document.getDocumentCatalog().getAllPages();
//for (int i = 0; i < allPages.size(); i++) {
for (int i = 99; i < 100; i++) {
PDPage page = (PDPage) allPages.get(i);
System.out.println("Processing page: " + i);
PDStream contents = page.getContents();
if (contents != null) {
printer.processStream(page, page.findResources(), page.getContents().getStream());
}
}
} finally {
if (document != null) {
document.close();
}
}
}
/**
* @param text The text to be processed
*/
@Override /* this is questionable, not sure if needed... */
protected void processTextPosition(TextPosition text) {
System.out.println("String[" + text.getXDirAdj() + ","
+ text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale="
+ text.getXScale() + " height=" + text.getHeightDir() + " space="
+ text.getWidthOfSpace() + " width="
+ text.getWidthDirAdj() + "]" + text.getCharacter());
System.out.append(text.getCharacter()+" <--------------------------------");
// System.out.println("String[" + text.getXDirAdj() + "," + text.getYDirAdj() + " fs=" + text.getFontSize() + " xscale=" + text.getXScale() + " height=" + text.getHeightDir() + " space=" + text.getWidthOfSpace() + " width=" + text.getWidthDirAdj() + "]" + text.getCharacter());
System.out.println(text.getFont().getBaseFont()); System.out.println(" Italic="+text.getFont().getFontDescriptor().isItalic());
System.out.println(" Bold="+text.getFont().getFontDescriptor().getFontWeight());
System.out.println(" ItalicAngle="+text.getFont().getFontDescriptor().getItalicAngle());
//try{
System.out.println(" xxxx="+text.getFont().getFontDescriptor().isFixedPitch());
//} catch (IOException ioex){}
}
}
答案 0 :(得分:2)
这个程序适用于我创建的PDF文件,但我必须获得Stedman's Dictionary.pdf的粗体和斜体信息,这似乎有一个隐藏此信息的技巧。
您的程序也适用于Stedman的词典:PDF中这些词典样式页面上的文本信息使用相同的字体,包括普通,粗体,斜体等文本。样式仅出现在叠加图像中,这仅仅是图像而不是文本提取的信息来源。
详细说明:
看例如进入第132个文档页面的内容流(编号为110,随机选择)显示以下条目
以下来源:
/F1 22 Tf
BT
1 0 0 1 61 2559 Tm
(Bal'four's)Tj
ET
/F1 21.46 Tf
BT
1 0 0 1 210 2559 Tm
(disease')Tj
ET
/F1 24.76 Tf
BT
1 0 0 1 327 2561 Tm
([George)Tj
ET
/F1 22.71 Tf
BT
1 0 0 1 444 2563 Tm
(Williatn)Tj
ET
/F1 23.33 Tf
BT
1 0 0 1 565 2564 Tm
(Balfour,)Tj
ET
/F1 24.76 Tf
BT
1 0 0 1 692 2566 Tm
(English)Tj
ET
/F1 23 Tf
BT
1 0 0 1 94 2525 Tm
(physician,)Tj
ET
/F1 24.09 Tf
BT
1 0 0 1 252 2526 Tm
(1822-1903.])Tj
ET
/F1 25.93 Tf
BT
1 0 0 1 447 2530 Tm
(Chloroma.)Tj
ET
即。相同的字体( F1 )用于每个单词,没有不同的样式,只是大小不同:
(坐标在手边的页面上缩放了0.23945倍;因此,PDFBox将为您提供按该因子缩放的数字,而不是列出的尺寸。)
您看到粗体( Bal'four's disease')或斜体( Balfour,)文字的原因是此文字信息是在渲染模式3中“渲染”,即不可见,并在其上显示扫描图像。因此,您没有任何可靠的信息(缺少对该图像应用样式文本的OCR)。
据说,这些尺寸,如果试图看到任何相关性,对于粗体文本似乎较小,分界线介于22和22.5之间(我看过三四个字典条目的印象。因此,您可能会尝试从小尺寸中获得粗体。我不会指望这是一个肯定的事情,但是,一些粗体文字可能更大,一些非粗体更小
答案 1 :(得分:1)
Try this :
protected void processTextPosition(TextPosition text) {
boolean isBold,isItalic;
String s = null ;
if (text.getFont().getFontDescriptor() != null )
{
{
if (text.getFont().getFontDescriptor().isForceBold() ||
text.getFont().getFontDescriptor().getFontWeight() > 680 )
{
isBold = true;
// System.err.println(text.getCharacter()+"==1");
if (text.toString() == null || text.toString().isEmpty() ||
text.toString().trim().isEmpty()){
// System.err.println(text.getCharacter()+"2");
s = new StringBuilder().append("").append(text).toString();
out.print(s);
}
s = new StringBuilder().append("").append(text).toString();
out.print(s);
}
}
}
if (text.getFont().getFontDescriptor().isItalic())
{
isItalic = true;
}
if (text.toString() == null || text.toString().isEmpty() ||
text.toString().trim().isEmpty()){
s = new StringBuilder().append("").append(text).toString();
out.print(s);
}
}