Задали вопрос, а можно ли в C# программными средствами наложить 2 изображения друг на друга. И даже сами потом предложили какое-то жуткое решение с привлечением WinAPI, и чуть ли не ассемблера со злыми духами.
На самом деле, задача вполне себе решается стандартными средствами.
Итак, предположим, что у нас есть 2 изображения, оба они PNG с прозрачностью, и лежат в ресурсах нашего приложения. Например, флаг:
и герб:
под именами, соответственно
Properties.Resources.flag
и Properties.Resources.trizub_small
Сначала сделаем из изображений два объекта
Bitmap
://Берем целевое изображение
Bitmap TargetBitmap = Properties.Resources.flag;
//Берем накладываемое изображение
Bitmap OverlayBitmap = Properties.Resources.trizub_small;
Теперь надо создать результирующее изображение (оно будет пока пустым) нужного размера:
//Создаем результирующее изображение (пока пустое)
Bitmap ResultBitmap = new Bitmap(TargetBitmap.Width, TargetBitmap.Height,
PixelFormat.Format32bppArgb);
Откуда взяли высоту и ширину - понятно, третий параметр
PixelFormat
берется в зависимости от исходных изображений. Желательно, чтоб они совпадали по глубине цвета, иначе получится некрасиво, может потеряться прозрачность или произойти еще какая-нибудь бяка. Я сделал 2 изображения с прозрачностью (ARGB) и глубиной цвета 32 бита.Теперь нужно создать объект
Graphics
, который и будет заниматься совмещением изображений. Раз мы будем рисовать в пустом Bitmap ResultBitmap
, то и объект Graphics
создаем из него, воспользовавшись методом Graphics.FromImage()
://Создаем объект Graphics из результирующего изображения
Graphics graph = Graphics.FromImage(ResultBitmap);
Далее объект
graph
надо настроить://настраиваем метод совмещения изображений
graph.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
Если вместо
SourceOver
установить SourceCopy
, то потеряется вся прозрачность у накладываемого изображения, и будет некрасиво:Далее, производим отрисовку:
//рисуем основное изображение
graph.DrawImage(TargetBitmap, 0, 0);
//рисуем накладываемое изображение
graph.DrawImage(OverlayBitmap, (TargetBitmap.Width-OverlayBitmap.Width) /2,
(TargetBitmap.Height-OverlayBitmap.Heigh t)/2,
OverlayBitmap.Width,OverlayBitmap.Height) ;
Думаю, откуда взяты все координаты и размеры, понятно.
Осталось только присвоить
Bitmap'ы PictureBox'ам
Тут тоже ничего сложного и сверхъестественного нет.
Чтоб два раза не вставать, возьмем полученное выше изображение и уменьшим его:
//задаем новые размеры
int NewWidth = ResultBitmap.Width / 2;
int NewHeight = ResultBitmap.Height / 2;
//Настраиваем PictureBox для вывода уменьшенного изображения
pbResize.Size = new Size(NewWidth, NewHeight);
Создадим новый
Bitmap
для будущего уменьшенного изображения://создаем новый Bitmap для измененного изображения
Bitmap ResizeBitmap = new Bitmap(NewWidth,
NewHeight);
Опять создадим объект
Graphics
, который будет заниматься отрисовкой://создаем объект Graphics, который будет изменять размер
Graphics ResizeGraph = Graphics.FromImage(ResizeBitmap);
Поставим повыше качество изображения:
//ставим высокое качество
ResizeGraph.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMo de.High;
И делаем отрисовку:
//рисуем изображение с измененным размером
ResizeGraph.DrawImage(ResultBitmap, 0, 0, NewWidth, NewHeight);
В заметке я пропустил вывод изображений в
PictureBox'ы
, но он и так очевиден (в исходнике есть).Вот, что получилось:
Исходник примера на GitHub
Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2018/06/30/c-wi