【问题标题】:Create measure dictionary for area annotation in iText在 iText 中为区域注释创建度量字典
【发布时间】:2019-11-02 04:37:08
【问题描述】:

该值的假定值为 15.2 平方厘米。但是,当注释被移动时,它变成了 0.04 平方厘米。

我从我的应用程序中获得了这些数据,其中面积计算为 9658.6572265625,其校准值为 0.00157889,结果为 15.2。

当提供pdf空间中的对应坐标时(见下面的代码),计算的面积为5433.001953125。

所以我像这样计算 pdf 空间中的校准值。

比率 = 面积 / pdfArea pdfCalibrationValue = 0.00157889 * 比率;

结果是 0.002806911838696635。如果计算出来

5433.001953125 x 0.002806911838696635 = 15.2

所以我想知道为什么结果变成 0.04。

想法?

public class Test {

    public static void main(String[] args) throws Exception {
        PdfReader reader = new PdfReader("src.pdf");
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("result.pdf"));

        Rectangle location = new Rectangle(426.582f, 514.291f, 559.0f, 613.818f);
        float[] floats = new float[] { 
            427.582f, 582.873f,
            493.036f, 515.291f,
            558.0f, 554.237f,
            527.4f, 612.818f,
            464.727f, 564.709f,
            427.582f, 582.873f
        };

        PdfArray pdfVertices= new PdfArray(floats);
        float calib = 0.002806911838696635f;

        PdfAnnotation stamp = PdfAnnotation.createPolygonPolyline(stamper.getWriter(), 
            location, "15.2 sq cm", true, new PdfArray(pdfVertices));
        stamp.setColor(BaseColor.RED);
        stamp.setBorderStyle(new PdfBorderDictionary(1, PdfBorderDictionary.STYLE_SOLID));
        stamp.put(PdfName.SUBTYPE, PdfName.POLYGON);
        stamp.put(new PdfName("IT"), new PdfName("PolygonDimension"));
        stamp.put(PdfName.MEASURE, createMeasureDictionary(calib));

        stamper.addAnnotation(stamp, 1);
        stamper.close();
        reader.close();
    }

    private static PdfDictionary createMeasureDictionary(float pdfCalibrationValue) {
        String unit = "cm";

        PdfDictionary measureDictionary = new PdfDictionary();
        measureDictionary.put(PdfName.TYPE, PdfName.MEASURE);
        measureDictionary.put(PdfName.R, new PdfString("1 " + unit + " = 1 " + unit));

        PdfDictionary xDictionary = new PdfDictionary();
        xDictionary.put(PdfName.TYPE, PdfName.NUMBERFORMAT);
        xDictionary.put(PdfName.U, new PdfString(unit));
        xDictionary.put(PdfName.C, new PdfNumber(pdfCalibrationValue));
        PdfArray xarr = new PdfArray();
        xarr.add(xDictionary);
        measureDictionary.put(PdfName.X, xarr);

        PdfDictionary dDictionary = new PdfDictionary();
        dDictionary.put(PdfName.TYPE, PdfName.NUMBERFORMAT);
        dDictionary.put(PdfName.U, new PdfString(unit));
        dDictionary.put(PdfName.C, new PdfNumber(1));
        PdfArray darr = new PdfArray();
        darr.add(dDictionary);
        measureDictionary.put(PdfName.D, darr);

        PdfDictionary aDictionary = new PdfDictionary();
        aDictionary.put(PdfName.TYPE, PdfName.NUMBERFORMAT);
        aDictionary.put(PdfName.U, new PdfString("sq " + unit));
        aDictionary.put(PdfName.C, new PdfNumber(1));
        PdfArray aarr = new PdfArray();
        aarr.add(aDictionary);
        measureDictionary.put(PdfName.A, aarr);

        return measureDictionary;
    }        

}

【问题讨论】:

    标签: dictionary annotations itext area measure


    【解决方案1】:

    您已计算出平移区域的系数:

    结果是 0.002806911838696635。如果计算出来

    5433.001953125 x 0.002806911838696635 = 15.2

    但随后您将这个用于未更改区域的因子用作 X 数字格式数组中的转换因子。

    X 数字格式数组是数字格式数组,用于测量沿 x 轴的变化,如果不存在 Y,则沿 y 轴也是。

    因此,由于您没有 Y 条目,因此您的面积系数必须是 X 平方的转换系数!

    换句话说,使用你的面积换算系数的平方根作为X换算系数,即替换

    float calib = 0.002806911838696635f;
    

    通过

    float calib = (float)Math.sqrt(0.002806911838696635);
    

    现在的结果好多了:

    但这并不完全是您的 15.2 平方厘米。因此,我检查了您的数字,确实,您在多边形区域中的 5433.001953125 值略有偏差,应该在 5388.9613 附近。

    使用这个更正确的值,我再次替换了上面的行,这次是:

    float calib = (float)Math.sqrt(15.2/5388.96);
    

    结果:

    【讨论】:

    • 谢谢@mkl。我使用我现有的公式让它工作。我添加的唯一更改是您更正的 Math.sqrt() 加上我得到的比率必须乘以 2 [ double pdfCalibrationValue = 0.00157889 * (ratio * 2);]。
    • 太棒了!由于这个答案(同样my answeryour previous question)暗示了您各自问题的解决方案,您应该将它们标记为已接受的答案(单击答案左上角的勾号,就在投票箭头的正下方)。
    • @chitgoks “第一次这样做” - 啊。那么您可能也应该查看您的旧问题。如果他们分别有解决问题的答案,您应该接受该答案。顺便说一句,如果接受,您和回答者都会获得声誉积分(除非您接受自己写的答案,以使漏洞利用更加困难)。
    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 2010-09-21
    • 2021-04-16
    • 2023-04-10
    相关资源
    最近更新 更多