2011-02-14 106 views
8

Related Question如何將縮放圖像上的XY座標和高度/寬度轉換爲原始大小的圖像?

我想做的事情,在鏈接的問題,但用C#。我正在顯示縮放的圖像,並允許用戶選擇要裁剪的區域。但是,我不能只從縮放的圖像選擇中獲取x1y1,x2y2座標,並從原始圖像中裁剪。我試過在另一個問題上做一些基本的數學運算,但這顯然不是正確的方法(它絕對更接近)。

編輯

初始圖像尺寸:w = 1024 h = 768

縮放圖像尺寸:w = 550 h = 412

我開始用圖像,說1024×768。我希望它在550x550盒子中儘可能大。我使用以下方法獲取縮放後的圖像大小(同時保持寬高比)。然後,我會對這些新維度進行基本調整。

至於選區,它可以是任何東西(0,0)到(100,100)。

private static Rectangle MaintainAspectRatio(Image imgPhoto, Rectangle thumbRect) 
{ 
    int sourceWidth = imgPhoto.Width; int sourceHeight = imgPhoto.Height; int sourceX = 0; int sourceY = 0; int destX = 0; int destY = 0; 

    float nPercent = 0; 
    float nPercentW = 0; 
    float nPercentH = 0; 

    nPercentW = ((float)thumbRect.Width/(float)sourceWidth); 
    nPercentH = ((float)thumbRect.Height/(float)sourceHeight); 

    //if we have to pad the height pad both the top and the bottom 
    //with the difference between the scaled height and the desired height 
    if (nPercentH < nPercentW) 
    { 
     nPercent = nPercentH; 
     destX = (int)((thumbRect.Width - (sourceWidth * nPercent))/2); 
    } 
    else 
    { 
     nPercent = nPercentW; 
     destY = (int)((thumbRect.Height - (sourceHeight * nPercent))/2); 
    } 

    int destWidth = (int)(sourceWidth * nPercent); 
    int destHeight = (int)(sourceHeight * nPercent); 

    Rectangle retRect = new Rectangle(thumbRect.X, thumbRect.Y, destWidth, destHeight); 
    return retRect; 
} 
+1

其中是縮放圖像的零點?在左上方還是左下方? – 2011-02-14 16:43:11

+0

我假設左上角 – scottm 2011-02-14 16:43:46

+1

您使用變換(2x2矩陣)縮放圖像。用該矩陣的逆來執行座標轉換。請提供具體的原始圖像大小,位置以及變換後的圖像大小,位置的數字示例 - 這使得有些人可以更容易地這樣思考,並且消除了一些不明確之處。 – 2011-02-14 16:44:08

回答

7

沒有更詳細一點,我猜你真的是患上四捨五入錯誤...
- 將(頂部,左側)座標縮放回原始位置時,需要向下取整(朝左上方)。
- 當你縮放(底部,右)統籌回原來的,你需要圍捕(向右底部)

以一個12×12網格,原來的一個簡單的例子,一個4×4網格作爲縮放版本。
- 縮放版本上的(1,1):(2,2)=(3,3):(8,8)
-2x2像素=縮放版本的面積的25%
-6x6像素=原始版本面積的25%

如果只是簡單地乘以相同的縮放因子,則會得到(3,3):(6,6)。


OriginalTop = INT(ScaledTop * YScalingFactor);
OriginalLeft = INT(ScaledLeft * XScalingFactor); OriginalBottom = INT((ScaledBottom + 1)* YScalingFactor) - 1;其中, OriginalRight = INT((ScaledRight + 1)* XScalingFactor) - 1;


編輯

解釋什麼,我想說的是制定一個承受力的一種更好的方式。我吮吸ASCII藝術。所以這裏是另一個嘗試用詞。

像素不是一個點。它本身就是一個小矩形。

當您使用像素來表示矩形的左上角時,您將包含像素左上角最左側的區域。

當您使用像素來表示一個長方形的右下,你包括這個地區的所有方式向右下大部分的像素點。


使用(12×12)=>(4×4)例如再次,每個縮放的像素表示一個整體的3x3組原始像素。當談到左上角時,您會選擇原始圖像中3x3像素組的左上角像素。當談到右下角時,您會選擇原始圖像中3x3像素組的右下角。


編輯:只使用整數。

NewTop = (( OldTop ) * NewHeight/OldHeight); 
NewLeft = (( OldLeft ) * NewWidth/OldWidth); 

NewBottom = ((OldBottom + 1) * NewHeight/OldHeight) - 1; 
NewRight = ((OldRight + 1) * NewWidth/OldWidth) - 1; 


唯一要考慮的是確保你沒有乘法溢出後您的數據類型。但有了圖像,你不會,除非它是一個圖像的地獄。

0

你可以得到的縮放圖像的百分比位置,並把它們放回COORDS爲未縮放圖像:

pX1 = scaledX1/scaled_width 
pY1 = scaledY1/scaled_height 

unscaledX1 = ceiling(unscaled_width * pX1) 
unscaledY1 = ceiling(unscaled_height * pY1) 
相關問題