我在pdfbox上做了一些实验,我现在遇到了一个问题,我怀疑这个问题与坐标系有关。
我正在扩展PDFTextStripper以获得pdf页面中每个字符的X和Y。
最初我是用ImageIO创建一个图像,在我收到的位置打印文本,并在我想要的每个引用的底部加上一个小标记(不同颜色的矩形),看起来一切都很好。但现在,为了避免丢失pdf的样式,我只想覆盖pdf并添加前面说过的标记,但我得到的坐标在PDPageContentStream中不匹配。
有关将pdf坐标从PDFTextStripper->processTextPosition匹配到可视坐标的任何帮助
使用版本1.8.11
正如注释中所讨论的,这是DrawPrintTextLocations工具的1.8版本,它是2.0版本的示例集合的一部分,并且基于更知名的PrintTextLocations示例。与2.0版本不同,这个版本没有显示字体边界框,只显示文本提取大小,大约是一个小字形的高度(a,e等)。它被用作文本抽取的启发式工具。这就是“我得到的textpositions是一半”效果的原因。如果您需要边界框,最好使用2.0(可能太大了)。要获得准确的大小,您必须计算每个字形的路径,并得到该字形的边界,同样,您需要2.0版本的字形。
public class DrawPrintTextLocations extends PDFTextStripper
{
private BufferedImage image;
private final String filename;
static final int SCALE = 4;
private Graphics2D g2d;
private final PDDocument document;
/**
* Instantiate a new PDFTextStripper object.
*
* @param document
* @param filename
* @throws IOException If there is an error loading the properties.
*/
public DrawPrintTextLocations(PDDocument document, String filename) throws IOException
{
this.document = document;
this.filename = filename;
}
/**
* This will print the documents data.
*
* @param args The command line arguments.
*
* @throws IOException If there is an error parsing the document.
*/
public static void main(String[] args) throws IOException
{
if (args.length != 1)
{
usage();
}
else
{
PDDocument document = null;
try
{
document = PDDocument.load(new File(args[0]));
DrawPrintTextLocations stripper = new DrawPrintTextLocations(document, args[0]);
stripper.setSortByPosition(true);
for (int page = 0; page < document.getNumberOfPages(); ++page)
{
stripper.stripPage(page);
}
}
finally
{
if (document != null)
{
document.close();
}
}
}
}
private void stripPage(int page) throws IOException
{
PDPage pdPage = (PDPage) document.getDocumentCatalog().getAllPages().get(page);
image = pdPage.convertToImage(BufferedImage.TYPE_INT_RGB, 72 * SCALE);
PDRectangle cropBox = pdPage.getCropBox();
g2d = image.createGraphics();
g2d.setStroke(new BasicStroke(0.1f));
g2d.scale(SCALE, SCALE);
setStartPage(page + 1);
setEndPage(page + 1);
Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream());
writeText(document, dummy);
// beads in green
g2d.setStroke(new BasicStroke(0.4f));
List<PDThreadBead> pageArticles = pdPage.getThreadBeads();
for (PDThreadBead bead : pageArticles)
{
PDRectangle r = bead.getRectangle();
GeneralPath p = transform(r, Matrix.getTranslatingInstance(-cropBox.getLowerLeftX(), cropBox.getLowerLeftY()));
AffineTransform flip = new AffineTransform();
flip.translate(0, pdPage.findCropBox().getHeight());
flip.scale(1, -1);
Shape s = flip.createTransformedShape(p);
g2d.setColor(Color.green);
g2d.draw(s);
}
g2d.dispose();
String imageFilename = filename;
int pt = imageFilename.lastIndexOf('.');
imageFilename = imageFilename.substring(0, pt) + "-marked-" + (page + 1) + ".png";
ImageIO.write(image, "png", new File(imageFilename));
}
/**
* Override the default functionality of PDFTextStripper.
*/
@Override
protected void writeString(String string, List<TextPosition> textPositions) throws IOException
{
for (TextPosition text : textPositions)
{
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());
// in red:
// show rectangles with the "height" (not a real height, but used for text extraction
// heuristics, it is 1/2 of the bounding box height and starts at y=0)
Rectangle2D.Float rect = new Rectangle2D.Float(
text.getXDirAdj(),
(text.getYDirAdj() - text.getHeightDir()),
text.getWidthDirAdj(),
text.getHeightDir());
g2d.setColor(Color.red);
g2d.draw(rect);
}
}
/**
* This will print the usage for this document.
*/
private static void usage()
{
System.err.println("Usage: java " + DrawPrintTextLocations.class.getName() + " <input-pdf>");
}
/**
* Transforms the given point by this matrix.
*
* @param x x-coordinate
* @param y y-coordinate
*/
private Point2D.Float transformPoint(Matrix m, float x, float y)
{
float[][] values = m.getValues();
float a = values[0][0];
float b = values[0][1];
float c = values[1][0];
float d = values[1][1];
float e = values[2][0];
float f = values[2][2];
return new Point2D.Float(x * a + y * c + e, x * b + y * d + f);
}
/**
* Returns a path which represents this rectangle having been transformed by the given matrix.
* Note that the resulting path need not be rectangular.
*/
private GeneralPath transform(PDRectangle r, Matrix matrix)
{
float x1 = r.getLowerLeftX();
float y1 = r.getLowerLeftY();
float x2 = r.getUpperRightX();
float y2 = r.getUpperRightY();
Point2D.Float p0 = transformPoint(matrix, x1, y1);
Point2D.Float p1 = transformPoint(matrix, x2, y1);
Point2D.Float p2 = transformPoint(matrix, x2, y2);
Point2D.Float p3 = transformPoint(matrix, x1, y2);
GeneralPath path = new GeneralPath();
path.moveTo((float) p0.getX(), (float) p0.getY());
path.lineTo((float) p1.getX(), (float) p1.getY());
path.lineTo((float) p2.getX(), (float) p2.getY());
path.lineTo((float) p3.getX(), (float) p3.getY());
path.closePath();
return path;
}
}
本文向大家介绍realm 打印文件位置-Swift,包括了realm 打印文件位置-Swift的使用技巧和注意事项,需要的朋友参考一下 示例 将以下行添加到ViewDidLoad方法: 上面的行会将位置打印到Xcode的控制台。复制文件路径,转到Finder →转到→转到文件夹...(或⌘+⇧+ G)→粘贴路径并单击转到。
本文向大家介绍realm 打印文件位置-Objective-C,包括了realm 打印文件位置-Objective-C的使用技巧和注意事项,需要的朋友参考一下 示例 使用以下命令记录领域文件位置: 上面的行会将位置打印到Xcode的控制台。复制文件路径,转到Finder →转到→转到文件夹...(或⌘+⇧+ G)→粘贴路径并单击转到。
公共静态地图>hillsByCounty(列表山){ }我的hashmap的值为(列表中的山名、国家名、高度、经度和纬度)。但是,我只需要打印3个县,每个县的前3个山及其高度,我该怎么做?在这里输入图像描述
问题内容: 我有一个文本文件,需要将其打印到特定的网络打印机。我知道打印机的名称。 到目前为止,我已经创建了Printable类来打印文件(票证)。 我这样称呼TicketPrintPage: 它的工作原理还不错,但是: -我的文本不多于一页(找到了一些算法,但是很好) -我不知道打印机何时完成打印,如果我尝试打印两页如果打印机连续打印了多张票证,则会返回“打印机未就绪”消息。 所以问题又来了:没
我想摘录: 图像标记和 类数据内的锚标记文本 我成功地提取了img src,但从锚标记中提取文本时遇到了问题。 这是整个HTML页面的链接。 这是我的代码: 我试图做的是提取图像src(link)和div class=data中的标题,例如: 应提取: 尼康COOLPIX L26 16.1 MP数码相机,配备5倍变焦NIKKOR玻璃镜头和3英寸LCD(红色)
问题内容: 在Python中,是否可以通过控制台中的input()请求用户输入,同时在提示之前的行中打印出文本?它看起来应该像这样: 每当打印新文本时,都应在前一个文本之后和input()提示符之前打印它。而且,它不应打扰用户输入文本。 因此,在打印“文本4”之后,控制台应如下所示: 在不使用任何外部库的情况下用Python可以做到吗? 我已经尝试使用\ r,\ b和类似的代码以及线程。我也知道我