2

我很难弄清楚如何计算裁剪任何纵横比高于 4:3 到 4:3 的图像的数学方法。

例如,我可能有一些 16:9 的图像需要调整大小,然后裁剪为 4:3。

我已经使用的调整大小位,但它保持相同的纵横比。我知道我需要使用Graphics.DrawImage()但我不完全确定参数应该是什么,也不知道如何导出这些参数。

以下是我所知道的:

var dimension = (double)bigSide/smallSide
if(dimension > 1.4)
{
  Graphics.DrawImage(resImage, new Rectangle(?, ?, ?, ?), ?, ?, ?, ?, GraphicsUnit.Pixel);
}

所以所有这些问号都是我不明白的参数。我也不确定将图像缩小到 4:3 需要什么样的数学运算。

本质上,我只是想从比 4:3 宽的图像(居中)切掉侧面。显然,我会剪切纵向而不是横向的图像的顶部和底部。

任何帮助将不胜感激。

TIA

4

3 回答 3

7

我看到您评论说您还想将裁剪后的图像调整为更小的尺寸,对吗?

Image resizeImg(Image img, int width)
    {
        // 4:3 Aspect Ratio. You can also add it as parameters
        double aspectRatio_X = 4;
        double aspectRatio_Y = 3;                        
        double targetHeight = Convert.ToDouble(width) / (aspectRatio_X / aspectRatio_Y);

        img = cropImg(img);
        Bitmap bmp = new Bitmap(width, (int)targetHeight);
        Graphics grp = Graphics.FromImage(bmp);
        grp.DrawImage(img, new Rectangle(0, 0, bmp.Width, bmp.Height), new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);
        return (Image)bmp;

    }

    Image cropImg(Image img)
    {
        // 4:3 Aspect Ratio. You can also add it as parameters
        double aspectRatio_X = 4;
        double aspectRatio_Y = 3;

        double imgWidth = Convert.ToDouble(img.Width);
        double imgHeight = Convert.ToDouble(img.Height);

        if (imgWidth / imgHeight > (aspectRatio_X / aspectRatio_Y))
        {
            double extraWidth = imgWidth - (imgHeight * (aspectRatio_X / aspectRatio_Y));
            double cropStartFrom = extraWidth / 2;
            Bitmap bmp = new Bitmap((int)(img.Width - extraWidth), img.Height);
            Graphics grp = Graphics.FromImage(bmp);                                                
            grp.DrawImage(img, new Rectangle(0, 0, (int)(img.Width - extraWidth), img.Height), new Rectangle((int)cropStartFrom, 0, (int)(imgWidth - extraWidth), img.Height), GraphicsUnit.Pixel);
            return (Image)bmp;
        }
        else
            return null;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        pictureBox2.Image = resizeImg(pictureBox1.Image, 60);
    }

使用 resize 方法并提供宽度作为参数。无需添加高度,因为它是通过裁剪方法完成的。

于 2013-08-28T19:56:06.727 回答
1

这是一种裁剪更宽图像的方法,以便您理解这个概念。

首先计算图像的额外宽度。即它占用了多少额外空间,超过 4:3 的比例。

考虑我想将 1366 x 768 图片裁剪为 1024 x 768。

这里我们可以用高度(768px)计算extra_width:

4 / 3 * (768) = 1024

因此,这为您提供了 768 高度的目标宽度。

现在额外的宽度是:

1366 - 1024

现在您可以通过将起始裁剪点设置为 extra_width 的 1/2 来裁剪图像,然后选择 full_height。

  Image cropImg(Image img)
    {
        // 4:3 Aspect Ratio. You can also add it as parameters
        double aspectRatio_X = 4;
        double aspectRatio_Y = 3;

        double imgWidth = Convert.ToDouble(img.Width);
        double imgHeight = Convert.ToDouble(img.Height);

        if (imgWidth / imgHeight > (aspectRatio_X / aspectRatio_Y))
        {
            double extraWidth = imgWidth - (imgHeight * (aspectRatio_X / aspectRatio_Y));
            double cropStartFrom = extraWidth / 2;
            Bitmap bmp = new Bitmap((int)(img.Width - extraWidth), img.Height);
            Graphics grp = Graphics.FromImage(bmp);                                                
            grp.DrawImage(img, new Rectangle(0, 0, (int)(img.Width - extraWidth), img.Height), new Rectangle((int)cropStartFrom, 0, (int)(imgWidth - extraWidth), img.Height), GraphicsUnit.Pixel);
            return (Image)bmp;
        }
        else
            return null;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        pictureBox2.Image = cropImg(pictureBox1.Image);
    }
于 2013-08-28T19:34:13.510 回答
0

答案在这里这里

Rectangle sourceRectangle = new Rectangle(0, 0, 1600, 900);

Rectangle destinationRectangle = new Rectangle(0, 0, 800, 600);

此代码以所需的纵横比裁剪图像部分,从 0,0 开始。您可以根据需要设置 x 坐标和 y 坐标,相对于图像中心进行计算。例如,如果您的图像是 1600 x 900 中心点是 800 和 450,那么要裁剪它的中心

Rectangle destinationRectangle = new Rectangle(400, 75, 800, 600);

这有点简化,但我希望你能抓住重点。

于 2013-08-28T17:56:37.957 回答