可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm having a tough time wrapping my head around how to figure out the math for cropping any image that has a higher aspect ratio than 4:3 to 4:3.
For example, I may have some images that are 16:9 that I I want resized and then cropped to 4:3.
The resize bit I already have working, but it's maintaining the same aspect ratio. I know I need to use Graphics.DrawImage()
But I'm not entirely sure what the parameters should be nor how I derive those parameters.
Here's what I do know:
var dimension = (double)bigSide/smallSide
if(dimension > 1.4)
{
Graphics.DrawImage(resImage, new Rectangle(?, ?, ?, ?), ?, ?, ?, ?, GraphicsUnit.Pixel);
}
so all of those question marks are parameters that I do not understand. I also am not sure what the math would need to look like for cutting down the image to 4:3.
Essentially I just want to cut the sides off of an image (center it) that is wider than a 4:3 aspect. Obviously I'd cut the top and bottom of an image that is portrait instead of landscape.
Any help would be greatly appreciated.
TIA
回答1:
I saw you've commented that you want also to resize the cropped image to a smaller size right?
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);
}
Use the resize method and provide width as parameter. No need to add height because it is done by the crop method.
回答2:
Here's a method for cropping a wider image, so that you can understand the concept.
First calculate the extra width of the image. i.e how much additional space it is taking more than a 4:3 ratio of the same.
Consider I want to crop a 1366 x 768 picture to 1024 x 768.
Here we can calculate the extra_width with the height (768px):
4 / 3 * (768) = 1024
So, that gives you the target width for a 768 height.
Now the extra width is:
1366 - 1024
Now you can crop the image by putting the starting crop point to 1/2 of the extra_width, and select the 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);
}
回答3:
Answers are here and here
Rectangle sourceRectangle = new Rectangle(0, 0, 1600, 900);
Rectangle destinationRectangle = new Rectangle(0, 0, 800, 600);
This code crops image part with required aspect ratio, starting from 0,0. You may set x-coordinate and y-coordinate as you like, calculating it in relation to image center. For example if your image is 1600 x 900 centre point is 800 and 450 so to crop it's center
Rectangle destinationRectangle = new Rectangle(400, 75, 800, 600);
This is somewhat simplified but I hope that you'll catch the point.