簡體   English   中英

在java中獲取圖像的負DPI

[英]Getting negative DPI of a image in java

在將 pdf 轉換為圖像並找到其 DPI 的同時,為某些 pdf 獲取負 imageXScale 和 imageYScale。 使用的 Jar 是 pdfbox1.8.8 和 iText。

找到圖片 Im0 位置=602.64,451.08 尺寸=837px,626px 尺寸=-212.59799mm,-159.131mm

必須為 0 的位置具有一定的價值。 無法檢測到問題

OP 提到他使用pdfbox1.8.8 和 iText,但沒有進一步說明他如何使用這些庫中的任何一個從他的 PDF 中檢索值。

考慮到單詞imageXScaleimageYScale以及位置和大小輸出,我假設他使用了PrintImageLocations PDFBox 示例

PrintImageLocations 輸出的含義

此示例為頁面上某處繪制的位圖圖像執行以下輸出:

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");

錨點的位置,即圖像的原始左下角在頁面上繪制的位置。

// raw size in pixels
System.out.println("raw image size  = " + imageWidth + ", " + imageHeight + " in pixels");

圖像資源的原始寬度和高度,以像素為單位。 總是非負的。

// displayed size in user space units
System.out.println("displayed size  = " + imageXScale + ", " + imageYScale + " in user space units");

在頁面上繪制的圖像的寬度和高度。 負值可能意味着圖像資源不是從錨點向右和向上繪制,而是向左和向下繪制。

// displayed size in inches at 72 dpi rendering
imageXScale /= 72;
imageYScale /= 72;
System.out.println("displayed size  = " + imageXScale + ", " + imageYScale + " in inches at 72 dpi rendering");

假設用戶空間單位寬度為 1/72 英寸(默認值),則在頁面上繪制的圖像的寬度和高度(以英寸為單位)。 可能會出現負值,見上文。

// displayed size in millimeters at 72 dpi rendering
imageXScale *= 25.4;
imageYScale *= 25.4;
System.out.println("displayed size  = " + imageXScale + ", " + imageYScale + " in millimeters at 72 dpi rendering");

假設用戶空間單位寬度為 1/72 英寸(默認值),則在頁面上繪制的圖像的寬度和高度(以毫米為單位)。 可能會出現負值,見上文。

因此,此處的負值具有與任何 DPI 屬性無關的含義(鏡像或 180° 旋轉)。 因此,要計算 DPI 值,請僅使用絕對值,忽略符號。

PDFBox 中的不一致

上面使用的 x 和 y 縮放因子來自當前的變換矩陣,如下所示:

/**
 * Returns the x-scaling factor of this matrix. This is calculated from the scale and shear.
 *
 * @return The x-scaling factor.
 */
public float getScalingFactorX()
{
    float xScale = single[0];

    /**
     * BM: if the trm is rotated, the calculation is a little more complicated
     *
     * The rotation matrix multiplied with the scaling matrix is:
     * (   x   0   0)    ( cos  sin  0)    ( x*cos x*sin   0)
     * (   0   y   0) *  (-sin  cos  0)  = (-y*sin y*cos   0)
     * (   0   0   1)    (   0    0  1)    (     0     0   1)
     *
     * So, if you want to deduce x from the matrix you take
     * M(0,0) = x*cos and M(0,1) = x*sin and use the theorem of Pythagoras
     *
     * sqrt(M(0,0)^2+M(0,1)^2) =
     * sqrt(x2*cos2+x2*sin2) =
     * sqrt(x2*(cos2+sin2)) = <- here is the trick cos2+sin2 is one
     * sqrt(x2) =
     * abs(x)
     */
    if( !(single[1]==0.0f && single[3]==0.0f) )
    {
        xScale = (float)Math.sqrt(Math.pow(single[0], 2)+
                                  Math.pow(single[1], 2));
    }
    return xScale;
}

摘自 Matrix.java

雖然顯然有人對此進行了一些思考(看看評論!),但實現有些不一致:

  • 如果single[1]single[3]有非零值,則if塊中的計算會產生非負方法結果。
  • 但是,對於single[1]single[3]零值, single[0]原樣返回,這可能是負數。

一致的實現要么總是刪除符號,要么總是嘗試確定一個有意義的符號

此外,計算有點簡單,因為它只考慮可以寫為縮放和旋轉的乘積的變換矩陣。 這些是非常常見的類型,但目前還不是所有可能的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM