Как нарисовать изображение на весь прямоугольник, не связанный с фоном - PullRequest
0 голосов
/ 03 сентября 2018

Я использую Graphics.DrawImageUnscaledAndClipped, чтобы нарисовать изображение с моим конкретным размером, но оно не заполняет прямоугольник должным образом или не связано с фоном.
Например, у меня есть изображение с размерами 57x43, и я хочу заполнить свое изображение, растянув его до моего изображения с размерами 240x240:

Пример кода:

var image = Image.FromFile(mySourceImageFile);
var bmp = new Bitmap(240, 240);
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
using (var g = Graphics.FromImage(bmp))
{
    // ... some other codes
    g.Clear(Color.Aqua); // I use this to highlight whole image
    // ... some other codes
    g.DrawImageUnscaledAndClipped(image, rect);
    // ... some other codes
}

bmp.Save(myDestinationImageFile);

Мой исходный файл изображения:
My 57x43 Jpeg file

Файл моего конечного изображения:
enter image description here

Я должен добавить, что в моем файле изображения назначения у меня есть 5 пиксельных линий внизу и 4 строки справа от тех, на которые влияет фон, который не ожидается!
Как я могу нарисовать изображение или обрезанное изображение, чтобы заполнить мой прямоугольник без влияния его текущего фона?

Я должен также добавить, что это часть моего создаваемого целевого изображения, и я знаю, что для простого изменения размера я могу использовать Bitmap(image, w, h).
И тот же результат с использованием g.DrawImage(new Bitmap(image, 240, 240), 0, 0);

1 Ответ

0 голосов
/ 03 сентября 2018

Я обнаружил, что для игнорирования фона я могу установить CompositingMode на CompositingMode.SourceCopy.

CompositingMode.SourceCopy
Указывает, что при отображении цвета он перезаписывает цвет фона.

Так что моя лучшая попытка с его использованием:

var image = Image.FromFile(mySourceImageFile);
var bmp = new Bitmap(240, 240);
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
using (var g = Graphics.FromImage(bmp))
{
    g.CompositingMode = CompositingMode.SourceCopy;

    // And some other settings to improve quality
    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    g.CompositingQuality = CompositingQuality.HighQuality;
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g.SmoothingMode = SmoothingMode.HighQuality;

    g.Clear(Color.Aqua); // I use this to highlight whole image
    // ... some other codes
    g.DrawImageUnscaledAndClipped(image, rect);
    // ... some other codes
}

bmp.Save(myDestinationImageFile);

Но с этим решением границы смысла изображения размыты !!!
enter image description here

Обновление:
Очень плохой хакерский способ получить лучшие эффекты может быть таким - не рекомендуется -:
используя tempBmp, который больше исходного изображения с некоторыми повторяющимися частями, и используйте его вместо исходного изображения при изменении размера, что-то вроде этого:

var image = Image.FromFile(mySourceImageFile);
var bmp = new Bitmap(240, 240);
var tempBmp = new Bitmap(image.Width + 4, image.Height + 5);

using (var g = Graphics.FromImage(tempBmp))
{
    g.DrawImage(image, 0, 0);
    g.DrawImage(image, 4, 0);
    g.DrawImage(image, 0, 5);
    g.DrawImage(image, 4, 5);
    g.DrawImage(image, 2, 0);
    g.DrawImage(image, 2, 1);        
    g.DrawImage(image, 0, 2);
    g.DrawImage(image, 1, 2);
    g.DrawImage(image, 4, 2);
    g.DrawImage(image, 3, 2);        
    g.DrawImage(image, 2, 5);
    g.DrawImage(image, 2, 4);
    g.DrawImage(image, 2, 3);
    g.DrawImage(image, 2, 2);
}

using (var g = Graphics.FromImage(bmp))
{
    // ... some other codes
    g.Clear(Color.Aqua); // I use this to highlight whole image
    // ... some other codes
    var imageRect = new Rectangle(2, 2, image.Width, image.Height);
    var drawRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    g.DrawImage(tempBmp, drawRect, imageRect, GraphicsUnit.Pixel);
    // ... some other codes
}

bmp.Save(myDestinationImageFile);

И мой файл изображения назначения:
My destination image file

Итак, я жду лучшего решения;).

...