14

関連する質問

リンクされた質問と同じことをしようとしていますが、C#を使用しています。スケーリングされた画像を表示しており、ユーザーがトリミングする領域を選択できるようにしています。ただし、スケーリングされた画像の選択からx1y1、x2y2座標を取得して、元の画像から切り取ることはできません。私は他の質問のようにいくつかの基本的な計算を試みましたが、それは明らかに正しいアプローチではありません (間違いなく近いです)。

編集

元の画像の寸法:w = 1024 h = 768

スケーリングされた画像の寸法:w = 550 h = 412

1024x768 などの画像から始めます。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;
}
4

2 に答える 2

12

もう少し詳細がなければ、実際には丸め誤差に苦しんでいると思います
... )。
- (下、右) 座標を元に戻す場合は、(右下に向かって) 切り上げる必要があります。

オリジナルとして 12x12 グリッド、スケーリングされたバージョンとして 4x4 グリッドの簡単な例を取り上げます。
- 拡大版の (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;


編集

私が言おうとしていることを説明するより良い方法は、絵を描くことです. そしてアスキーアートが苦手です。では、もう一度言葉を試してみましょう。

ピクセルは点ではありません。それ自体は小さな長方形です。

ピクセルを使用して四角形の左上を表す場合、ピクセルの左上端の Point からの領域が含まれます。

ピクセルを使用して四角形の右下を表す場合、ピクセルの一番右下のポイントまでの領域を含めます。


(12x12) => (4x4) の例を再度使用すると、スケーリングされたすべてのピクセルは、元のピクセルの 3x3 セット全体を表します。左上について話すときは、元の 3x3 ピクセル グループの左上のピクセルを選択します。右下について言えば、元の 3x3 ピクセル グループの右下を選択します。


編集: 整数のみを使用します。

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

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


唯一の考慮事項は、乗算後にデータ型がオーバーフローしないようにすることです。しかし、画像の場合は、よほどの画像でない限り、そうはなりません。

于 2011-02-14T16:57:32.043 に答える
0

スケーリングされた画像のパーセント位置を取得し、それらをスケーリングされていない画像の座標に戻すことができます。

pX1 = scaledX1/scaled_width
pY1 = scaledY1/scaled_height

unscaledX1 = ceiling(unscaled_width * pX1)
unscaledY1 = ceiling(unscaled_height * pY1)
于 2011-02-14T16:53:28.410 に答える