0

ユーザーが画像をアップロードするときに、1600 X 700に拡大縮小できますか?

以下のコードを使用して、1996 X 1442の画像を拡大縮小していますが、1600X700に拡大縮小することはありません。

それを達成するためのより良い方法または他の方法はありますか?

private static Image resizeImage(Image imgToResize, Size size)
        {
            int sourceWidth = imgToResize.Width;
            int sourceHeight = imgToResize.Height;

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

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

            if (nPercentH < nPercentW)
                nPercent = nPercentH;
            else
                nPercent = nPercentW;

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

            Bitmap b = new Bitmap(destWidth, destHeight);
            Graphics g = Graphics.FromImage((Image)b);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;

            g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
            g.Dispose();

            return (Image)b;
        }

以下のコメントをチェックすると、アスペクト比を失うことなくアーカイブすることはできないと言われていますが、HEROの画像を見ると、1600X700の画像airbnbがあります...

だからどういうわけか可能だと思いますが、どうやって達成するのかわかりません...

4

4 に答える 4

2

もちろん、1600 x 700 は 1996 x 1442 (0.7724) とは異なる縦横比 (0.4375) を持っているため、違います。これを行う方法は、アスペクト比を維持したまま拡大縮小することなので、1996 x 1442 から 1600 x 700 になることはありません。

あなたは出来る:

  1. 長い方の角が 1600 の長さになるように画像を拡大縮小し、関連する部分を 1600 x 700 のサイズ (縦横比を維持) で切り取ります。
  2. 画像を 1600 x 700 にスケーリングします。垂直方向に「圧縮」されているため、おそらく画像が歪んでいます。

コードのもう 1 つの問題は、丸めの問題です。

int destWidth = (int)...;
int destHeight = (int)...;

小数点以下を切り捨てるだけです。計算結果が699.9だったdestWidthとしても699。

代わりに使用することをお勧めしますMath.Round。これにより、期待どおりに 699.9 が 700 に丸められます。

于 2012-12-21T08:51:52.157 に答える
1

まあ、実際にそうです!この世界で不可能なことはほとんどありません。「シームカービング」に関する情報を検索してみてください。申し訳ありませんが、私はこれらのアルゴリズムにあまり詳しくないので、ここにコードはありません。

于 2012-12-21T08:59:37.827 に答える
0

私はあなたの方法をいくつかの方法で微調整しました:

  1. 小さい比率ではなく、大きい比率に従ってスケーリングされるようになったため、白い (?) レターボックスを残すのではなく、画像からビットをトリミングすることになります。(これはただのvsですので簡単に変更できます。)<>
  2. 等しいはずの側については、スケーリングと丸めを行って 1 ピクセルの違いにならないようにするのではなく、これにより等しいことが保証されます。
  3. 縦横比が一致しない場合は、描画された画像が中央に配置されるgため、左右または上下が同じ量だけトリミングされます。(元の画像が正しい比率であることを知らずに、画像のどのビットを切り落とすかを何らかの方法で決定する必要があります。)

試してみて、結果が気に入るかどうかを確認してください。

private static Image resizeImage(Image imgToResize, Size size)
{
    int sourceWidth = imgToResize.Width;
    int sourceHeight = imgToResize.Height;

    double wRatio = (double)size.Width / sourceWidth;
    double hRatio = (double)size.Height / sourceHeight;

    int destWidth, destHeight;
    float top, left;

    if (wRatio > hRatio) // reverse for white bars rather than trimming
    {
        destWidth = size.Width;
        destHeight = (int)Math.Ceiling(sourceHeight * wRatio);
        left = 0;
        top = (destHeight - size.Height) / 2f;
    }
    else
    {
        destHeight = size.Height;
        destWidth = (int)Math.Ceiling(sourceWidth * hRatio);
        top = 0;
        left = (destWidth - size.Width) / 2f;
    }

    Bitmap b = new Bitmap(size.Width, size.Height);
    Graphics g = Graphics.FromImage((Image)b);
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

    g.DrawImage(imgToResize, left, top, destWidth, destHeight);
    g.Dispose();

    return (Image)b;
}
于 2012-12-21T08:54:30.570 に答える
-1

このコードは、元の画像の縦横比を保持します。保持することが重要でない場合は、比率計算部分を取り除き、サイズが直接指定された Bitmap オブジェクトを作成できます。

private static Image resizeImage(Image imgToResize, Size size)
{
    Bitmap b = new Bitmap(size.Width, size.Height);
    Graphics g = Graphics.FromImage((Image)b);
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;

    g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
    g.Dispose();

    return (Image)b;
}
于 2012-12-21T08:55:52.613 に答える