我希望将PDF渲染为图像,并在其上绘制所有包含图像的边框。为此,我需要页面上图像的正确尺寸。
这是使用以下代码:
public class PrintImageLocations extends PDFStreamEngine
{
@Override
protected void processOperator( Operator operator, List<COSBase> operands) throws IOException
{
String operation = operator.getName();
if( "Do".equals(operation) )
{
COSName objectName = (COSName) operands.get( 0 );
PDXObject xobject = getResources().getXObject( objectName );
if( xobject instanceof PDImageXObject)
{
PDImageXObject image = (PDImageXObject)xobject;
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
System.out.println("Found image " + objectName.getName());
Matrix ctmNew = getGraphicsState().getCurrentTransformationMatrix();
float imageXScale = ctmNew.getScalingFactorX();
float imageYScale = ctmNew.getScalingFactorY();
// position in user space units. 1 unit = 1/72 inch at 72 dpi
System.out.println("position in PDF = " + ctmNew.getTranslateX() + ", " + ctmNew.getTranslateY() + " in user space units");
}
else if(xobject instanceof PDFormXObject)
{
PDFormXObject form = (PDFormXObject)xobject;
showForm(form);
}
}
else
{
super.processOperator( operator, operands);
}
}
}
输出示例:用户空间单位中的位置PDF = 535.68,97.79052
不幸的是,当页面旋转时我遇到了问题。有很多pdf在“getCurrentPage()。getRotation()”上返回90。对于90度我必须切换getTranslateX和getTranslateY值才能获得正确的位置,但这只适用于90度。是否有任何酷的矩阵变换可用于旋转位置?
我认为在this代码中,作者试图解决这个旋转问题,但是1)我不明白转换正在做什么和第2)它不能正常工作,因为在旋转一个值之后否定。
答案 0 :(得分:0)
您可以使用以下旋转矩阵在欧几里德空间中执行旋转。
逆时针:
R = ⎡ cosθ -sinθ ⎤
⎣ sinθ cosθ ⎦
顺时针方向:
R = ⎡ cosθ sinθ ⎤
⎣ -sinθ cosθ ⎦
每个矩阵将在二维笛卡尔平面中旋转关于原点的角度θ。该技术假定每个点都表示为列向量v
。每个点的新值由R * v
计算,其中*
表示矩阵乘法。
此技术将至少对两个维度中的一个维度上的某些点产生负值(无论如何相对到初始值)。为了相对于笛卡尔原点对此进行校正,请将旋转后的图像“{上升”翻译min(y) - min(y')
,将“右”翻译为min(x) - min(x')
,其中min(d)
表示沿任意维度的最小值点。
因此,您不必自己完成所有样板操作,您应该查看AffineTransform
类。
答案 1 :(得分:0)
好的......我以为我可以用一些数学来运行它...不幸的是它不起作用(我觉得问题是坐在电脑前)
protected void processOperator(Operator operator, List<COSBase> operands) throws IOException {
String operation = operator.getName();
if ("Do".equals(operation)) {
COSName objectName = (COSName) operands.get(0);
PDXObject xobject = getResources().getXObject(objectName);
if (xobject instanceof PDImageXObject) {
PDImageXObject image = (PDImageXObject) xobject;
Matrix ctmNew = getGraphicsState().getCurrentTransformationMatrix();
float imageXScale = ctmNew.getScalingFactorX();
float imageYScale = ctmNew.getScalingFactorY();
int rotationDegree = getCurrentPage().getRotation();
float pageHeight = this.getCurrentPage().getBBox().getHeight();
float pageWidth = this.getCurrentPage().getBBox().getWidth();
float translateX;
float translateY;
if (rotationDegree == 0) {
translateX = ctmNew.getTranslateX();
translateY = pageHeight - ctmNew.getTranslateY() - imageYScale;
} else if (rotationDegree == 90) {
translateX = ctmNew.getTranslateY();
translateY = ctmNew.getTranslateX() - imageYScale;
} else if (rotationDegree == 270) {
translateX = pageHeight - ctmNew.getTranslateY();
translateY = pageWidth - ctmNew.getTranslateX() - imageYScale;
} else if (rotationDegree == 180) {
translateX=pageWidth - ctmNew.getTranslateX() -imageXScale ;
translateY=pageHeight - ctmNew.getTranslateY() - imageYScale;
logger.log(Level.INFO, "image rotation 180 degree. not fully tested yet");
}
else {
throw new RuntimeException("");
}
PdfImage pdfImage = new PdfImage(objectName.getName(), translateX, translateY, imageXScale, imageYScale, image.getImage());
pdfImages.add(pdfImage);
} else if (xobject instanceof PDFormXObject) {
PDFormXObject form = (PDFormXObject) xobject;
showForm(form);
}
} else {
super.processOperator(operator, operands);
}
}