InterpolationMode HighQualityBicubic представляет артефакты на краю измененных изображений
Использование некоторого довольно стандартного С# кода для изменения размера изображения и размещения его на цветном фоне
Image imgToResize = Image.FromFile(@"Dejeuner.jpg");
Size size = new Size(768, 1024);
Bitmap b = new Bitmap(size.Width, size.Height);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.FillRectangle(Brushes.Green, 0, 0, size.Width, size.Height);
g.DrawImage(imgToResize, new Rectangle(0,150,768, 570));
b.Save("sized_HighQualityBicubic.jpg");
Результат имеет забавный артефакт в 0-м и 1-м столбцах пикселей. 0-я колонка, кажется, смешана с цветом фона, и 1-й столбец стал легче.
См. верхний левый угол, увеличенный для бикубического и бикубического качества.
![HighQualityBicubic]()
![Bicubic]()
.. и HighQualityBilinear
![HighQualityBilinear]()
Это сообщение на форуме похоже на кого-то с той же проблемой: DrawImage с острыми краями
Звучит как ошибка для меня? Я могу понять, почему цвета будут смешиваться в верхней части измененного изображения. Но смешивание цветов на левом/правом краях не имеет смысла. Кто-нибудь знает об исправлении для предотвращения этих артефактов?
Обновление: очень похожий разговор происходит в комментариях здесь: GDI + InterpolationMode
Ответы
Ответ 1
Бесстыдно поднимая ответ из этого вопроса, я нашел, что это исправляет его:
using (ImageAttributes wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
g.DrawImage(input, rect, 0, 0, input.Width, input.Height, GraphicsUnit.Pixel, wrapMode);
}
Ответ 2
Ниже приведено изображение типичного изменения размера HighQualityBicubic
(нарисовано на белом фоне).
![Hosted by imgur.com]()
Вы можете видеть полупрозрачные пиксели по краям. Вы можете назвать это ошибкой. Я думаю, что это просто техническая деталь GDI+. И это просто, чтобы обойти этот артефакт.
1) Предотвращение сглаживания.
...
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// add below line
g.CompositingMode = CompositingMode.SourceCopy;
...
С CompositingMode.SourceCopy
результат будет показывать видимый контур, но не сглаживаться с фоновыми пикселями.
2) Обрезать полупрозрачную область
Вы можете полностью игнорировать эти полупрозрачные пиксели.
Image imgToResize = Image.FromFile(@"Dejeuner.jpg");
Size size = new Size(768, 1024);
Bitmap b = new Bitmap(size.Width, size.Height);
Graphics g = Graphics.FromImage((Image)b);
g.FillRectangle(Brushes.Green, 0, 0, size.Width, size.Height);
Bitmap b2 = new Bitmap(768 + 8, 570 + 8);
{
Graphics g2 = Graphics.FromImage((Image)b2);
g2.Clear(Color.White);
g2.InterpolationMode = InterpolationMode.HighQualityBicubic;
g2.DrawImage(imgToResize, new Rectangle(2, 2, 768 + 4, 570 + 4));
}
g.CompositingMode = CompositingMode.SourceCopy;
g.DrawImage(b2, 0, 150, new Rectangle(4, 4, 768, 570), GraphicsUnit.Pixel);
b.Save("sized_HighQualityBicubic.jpg");
Ответ 3
Задайте свойство PixelOffsetMode для HighQuality, чтобы получить лучшую смесь с фоном по краям.