Требуется несколько изменений, чтобы это работало должным образом:
Не используйте Image.Fromfile()
: если вам по какой-то причине необходимо всегда использовать перегрузку (string, bool
), что позволяет сохранить встроенную информацию управления цветом. Поскольку вы можете избежать этого, примите метод, показанный здесь, используя File.ReadAllBytes()
и MemoryStream
(или FileStream
в блоке using
).
Graphics.SetClip () не разрешает сглаживание. Это также относится к регионам (по крайней мере, без дополнительных корректировок). Здесь я использую TextureBru sh, специальную сборку bru sh из растрового изображения (вашего измененного растрового растрового изображения), которое затем используется для заполнения эллипса, который кроп изображение с измененным размером.
Утилизация создаваемых вами одноразовых объектов очень важна, особенно когда вы имеете дело с графическими объектами. Конечно, вам нужно избавиться от всех одноразовых объектов, которые вы создаете (объекты, которые предоставляют метод Dispose()
). Это включает в себя объект OpenFileDialog
.
Не используйте пути в этой форме: @"..\..\Image.png"
: этот путь не будет существовать (или он не будет недоступен, или просто неправильно ), когда Вы перемещаете свой исполняемый файл куда-то еще.
Всегда используйте Path.Combine () (как показано здесь), чтобы построить полный путь.
В этом примере изображение сохраняется внутри CroppedImages
подпапка в пути к исполняемому файлу.
Эта топи c довольно широка, хотя (например, вам может быть запрещено хранить данные в пути к исполняемому файлу, поэтому вам может потребоваться использовать выделенный путь в Пользовательская папка AppData
или каталог ProgramData
).
Все расчеты должны быть пересмотрены , посмотрите, что я разместил здесь.
private void Recorte_Click(object sender, EventArgs e)
{
using (var ofd = new OpenFileDialog()) {
ofd.Filter = "Image Files (*.jpg; *.jpeg; *.gif; *.bmp; *.png)|*.jpg; *.jpeg; *.gif; *.bmp; *.png";
ofd.RestoreDirectory = true;
if (ofd.ShowDialog() != DialogResult.OK) return;
Image croppedImage = null;
using (var sourceImage = Image.FromStream(new MemoryStream(File.ReadAllBytes(ofd.FileName))))
using (var resizedImage = ResizeImage(sourceImage, new Size(100, 300), false)) {
croppedImage = CropToCircle(resizedImage, Color.Transparent, Color.Turquoise);
pictureBox1.Image?.Dispose();
pictureBox1.Image = croppedImage;
string destinationPath = Path.Combine(Application.StartupPath, @"CroppedImages\Cortada.png");
croppedImage.Save(destinationPath, ImageFormat.Png);
}
}
}
Метод CropToCircle
переписан, и я добавил перегрузку, позволяющую указать цвет пера.
Затем перо будет использоваться для рисования границы вокруг обрезанная эллиптическая область.
public static Image CropToCircle(Image srcImage, Color backColor)
{
return CropToCircle(srcImage, backColor, Color.Transparent);
}
public static Image CropToCircle(Image srcImage, Color backColor, Color penColor)
{
var rect = new Rectangle(0, 0, srcImage.Width, srcImage.Height);
var cropped = new Bitmap(srcImage.Width, srcImage.Height, PixelFormat.Format32bppArgb);
using (var tBrush = new TextureBrush(srcImage))
using (var pen = new Pen(penColor, 2))
using (var g = Graphics.FromImage(cropped)) {
g.SmoothingMode = SmoothingMode.AntiAlias;
if (backColor != Color.Transparent) g.Clear(backColor);
g.FillEllipse(tBrush, rect);
if (penColor != Color.Transparent) {
rect.Inflate(-1, -1);
g.DrawEllipse(pen, rect);
}
return cropped;
}
}
Метод ResizeImage
упрощен.
- Коэффициент масштабирования, когда он используется, принимает максимальное значение нового указанного размера и изменяет размер изображения в соответствии с границами этого размера.
- Графика PixelOffsetMode установлена на
PixelOffsetMode.Half
. Примечания здесь объясняют, почему .
public static Image ResizeImage(Image image, Size newSize, bool preserveAspectRatio = true)
{
float scale = Math.Max(newSize.Width, newSize.Height) / (float)Math.Max(image.Width, image.Height);
Size imageSize = preserveAspectRatio
? Size.Round(new SizeF(image.Width * scale, image.Height * scale))
: newSize;
var resizedImage = new Bitmap(imageSize.Width, imageSize.Height);
using (var g = Graphics.FromImage(resizedImage)) {
g.PixelOffsetMode = PixelOffsetMode.Half;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(image, 0, 0, imageSize.Width, imageSize.Height);
}
return resizedImage;
}