C# 在C中从图像中心开始裁剪图像#
根据回答,我编写了以下代码,用于在保持纵横比正确的情况下调整图像大小:C# 在C中从图像中心开始裁剪图像#,c#,C#,根据回答,我编写了以下代码,用于在保持纵横比正确的情况下调整图像大小: 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, dimensio
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);
}
public静态元组GetImageDimensions(int-originalWidth、int-originalHeight、int-width、int-height)
{
双宽比=(双)原始高度/(双)原始宽度;
双倍高度=(双倍)原始宽度/(双倍)原始高度;
int newWidth=原始宽度;
int newHeight=原始高度;
如果(width.HasValue&&!height.HasValue&&width.Value,则可以使用System.Drawing.Image命名空间的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
您可以使用System.Drawing.Image命名空间的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
首先,我建议更改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);
}
现在,使用新尺寸为目标图像创建一个新位图。之后,您可以绘制到新图像中,提供位置和新尺寸作为源坐标:
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;
}
请注意:我没有尝试过此方法。您可能需要对内容进行微调,但您得到了图片…首先,我建议更改您的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);
}
现在,使用新尺寸为目标图像创建一个新位图。之后,您可以绘制到新图像中,提供位置和新尺寸作为源坐标:
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;
}
请注意:我没有尝试过此操作。您可能需要对内容进行微调,但您得到了图片…是否GetThumbnailImage
返回整个图像但调整了大小?我希望获得这种行为:对于这种功能,请参考此链接:不GetThumbnailImage
返回整个图像但调整了大小?我希望要获得这种行为:对于这种功能,请参考此链接:可能重复的可能重复的可能重复的可能重复的可能重复的可能重复的感谢!我仍在尝试让您的代码工作,因为没有超载的图形。DrawImage
喜欢在您的代码中。然后使用另一个。它实际上并不另外,目标位置必须是(0,0)
,目标维度必须是(newDimensions.Item1,newDimensions.Item2)
和源矩形需要按我的方式指定。还有其他重载允许您这样做。明白了,感谢您花时间帮助我给出详细答案!谢谢!我仍在尝试让您的代码正常工作,因为您的代码中没有类似于graphics.DrawImage的重载。然后使用另一个o不重要。目标位置必须是(0,0)
,目标维度必须是(newDimensions.Item1,newDimensions.Item2)
源矩形需要按照我的方式指定。还有其他重载允许您这样做。明白了,感谢您花时间帮助我给出详细答案!