在this回答之后,我制作了以下代码来调整图像大小,同时保持宽高比正确:
private static Bitmap ResizeImage(Image image, int? width, int? height)
{
var dimensions = GetImageDimensions(image.Width, image.Height, width, height);
var destRect = new Rectangle(0, 0, dimensions.Item1, dimensions.Item2);
var destImage = new Bitmap(dimensions.Item1, dimensions.Item2);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
我制作了以下方法来确定尺寸:
public static Tuple<int, int> GetImageDimensions(int originalWidth, int originalHeight, int? width, int? height)
{
double widthRatio = (double)originalHeight / (double)originalWidth;
double heighthRatio = (double)originalWidth / (double)originalHeight;
int newWidth = originalWidth;
int newHeight = originalHeight;
if (width.HasValue && !height.HasValue && width.Value <= originalWidth)
{
newWidth = width.Value;
newHeight = (int)(width.Value * widthRatio);
}
else if (!width.HasValue && height.HasValue && height.Value <= originalHeight)
{
newHeight = height.Value;
newWidth = (int)(height.Value * heighthRatio);
}
return new Tuple<int, int>(newWidth, newHeight);
}
我的问题:如果用户同时填充新的宽度和一个新的高度,而不是调整我想要裁剪的图像(从原始图像的中心像素开始)。看到这张图片:
如果我的图像原来是1000x1000像素(图像中的红色),并且我将它传递给我的方法以及新的with和height(均为500),我想要返回裁剪后的图像(绿色图片)。但是,无论我在ResizeImage
方法中更改了哪个参数,我似乎无法裁剪图像。在调用graphics.DrawImage
时,我尝试更改所有参数,但我似乎无法获得上图所示的结果。发生了什么事?
答案 0 :(得分:3)
您可以使用 System.Drawing.Image 命名空间的图像类,该命名空间返回预期广播中的图像。
例如:
Image image = Image.FromFile(path); // actual image
Image thumb = image.GetThumbnailImage(150, 150, () => false, IntPtr.Zero); //cropped image with height 150 and width 150
答案 1 :(得分:1)
首先,我建议更改您的GetImageDimensions
方法 - 它还应该返回是调整大小还是裁剪:
public static Tuple<int, int, bool> GetImageDimensions(int originalWidth, int originalHeight, int? width, int? height)
{
double widthRatio = (double)originalHeight / (double)originalWidth;
double heighthRatio = (double)originalWidth / (double)originalHeight;
int newWidth = originalWidth;
int newHeight = originalHeight;
bool cropping = false;
if (width.HasValue && !height.HasValue && width.Value <= originalWidth)
{
newWidth = width.Value;
newHeight = (int)(width.Value * widthRatio);
}
else if (!width.HasValue && height.HasValue && height.Value <= originalHeight)
{
newHeight = height.Value;
newWidth = (int)(height.Value * heighthRatio);
}
else
{
cropping = true;
}
return new Tuple<int, int>(newWidth, newHeight, cropping);
}
现在,基本上你需要以你想要的方式裁剪图像是新的尺寸和的位置。假设您的GetImageDimensions
方法返回正确的尺寸,您可以按如下方式计算位置:
var newDimensions = GetImageDimensions(...);
// We need to detect whether to resize or to crop
bool mustCrop = newDimensions.Item3;
// Initialize your SOURCE coordinates
int x = 0;
int y = 0;
int w = image.Width;
int h = image.Height;
// Adjust if we want to crop
if (mustCrop)
{
x = (image.Width - newDimensions.Item1) / 2;
y = (image.Height - newDimensions.Item2) / 2;
w = newDimensions.Item1;
h = newDimensions.Item2;
}
现在,您可以使用新尺寸为目标图像创建新的位图。之后,您可以绘制新图像,同时提供位置和新尺寸作为源坐标:
graphics.DrawImage(image, 0, 0, new Rectangle(x, y, w, h), GraphicsUnit.Pixel);
这应该处理缩放和裁剪。所以你的ResizeImage
方法看起来像这样:
private static Bitmap ResizeImage(Image image, int? width, int? height)
{
var dimensions = GetImageDimensions(image.Width, image.Height, width, height);
// We need to detect whether to resize or to crop
bool mustCrop = newDimensions.Item3;
// Initialize your SOURCE coordinates. By default, we copy
// then entire image, resizing it
int x = 0;
int y = 0;
int w = image.Width;
int h = image.Height;
// Adjust if we want to crop
if (mustCrop)
{
x = (image.Width - newDimensions.Item1) / 2;
y = (image.Height - newDimensions.Item2) / 2;
w = newDimensions.Item1;
h = newDimensions.Item2;
}
var destImage = new Bitmap(dimensions.Item1, dimensions.Item2);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, new Point(0,0), new Rectangle(x, y, w, h), GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
请注意:我没试过这个。你可以对事物进行微调,但是你得到了图片......