камрады!
Суть проблемы: нужно в интерактивном режиме ресайзить Bitmap порядка 3*4 тыщи пикселей или даже больше. Грубо говоря, зум.
Пробовал:
scaled = new Bitmap(baseImage, newSize);
Второй вариант:
Bitmap scaled = new Bitmap(size.Width, size.Height);
using (Graphics g = Graphics.FromImage((Image)scaled))
{
g.DrawImage(baseImage, 0, 0, size.Width, size.Height);
}
return scaled;
И разные вариации, но толку чуть меньше чем ноль. Единственное, что даёт прирост производительности - подключить OpenCV и использовать их ресайз, но таскать за собой такой хвост - идея не лучшая.
Возможно есть существующие библиотеки как на чистом C# или обёртки (у меня WinForms .net 3.5 проект) полегче того же OpenCV... ТОП Nugeta - обёртки над тем же new Bitmap и результата не дают. Или я плохо искал. В общем, я открыт для предложений.
UPD: информация к размышлению. У меня уже черепушка плавится.
Запускаю вот такой код с отрисовкой получившегося изображения прямо на контрол. Всё летает.
//прицеплено на Form1.paint
protected override void OnPaint(PaintEventArgs e)
{
var g = e.Graphics;
g.DrawImage(baseImage, new RectangleF(0, 0, baseImage.Width * Scale, baseImage.Height * Scale));
}
Но! Если получать Graphics объект не из PaintEventArgs, а из Graphics.FromImage(baseImage), то скорость работы строчки
g.DrawImage(baseImage, new RectangleF(0, 0, width, height));
разнится в разы. Вот это-то и смущает. Мне нужно не просто отрисовать изображение на контрол, а отрисовать его именно в конкретный объект. То есть, код:
scaledImage.Dispose();
scaledImage = new Bitmap(width, height);
var g = Graphics.FromImage(scaledImage);
g.DrawImage(baseImage, new RectangleF(0, 0, width, height));
Работает примерно в 10-12 раз медленнее кода:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
g.DrawImage(baseImage, new RectangleF(0, 0, baseImage.Width * Scale, baseImage.Height * Scale));
pictureBox1.Invalidate();
}
Здесь идёт отрисовка на контрол сразу и выполняется это почти моментально. Но мне нужно записать всё в Bitmap объект.
Самое забавное, что если перейти внутрь g.DrawImage(), то в обоих случаях вызывается один и тот же метод DrawImage из System.Drawing, но при одном объекте Graphics он летает, а при том, что мне нужно - полученном через Graphics.FromImage() - тормозит
Может быть выгодно разбить битмап на прямоугольные части.
Изображение такого размера ведь в большинстве случаев целиком не показывают, а масштабирование одной или, скажем, четырёх из 16 частей явно быстрее, чем всего большого битмапа.
Кроме того, можно предрассчитать - или заранее, или в начале работы программы - несколько копий в других масштабах.
Для показа целой картинки на стандартных мониторах отображаем готовую копию с масштабом 0.5 или 0.25. Если масштаб промежуточный - можно из тех же уменьшенных сделать.
Для увеличенного масштаба нарезанные куски хорошо подойдут.
Может, я что-то упустил, но почему-бы не использовать функционал доступный из коробки?
Ты используешь Winforms. У него есть PictureBox. У него есть режим Zoom. Просто меняешь скролом размер этого PictureBox и получаешь зум. Перемещение по картинке -- реализуй перетягивание PictureBox внутри некой панели по клику.
Ни тормозов не должно быть ни излишних ресайзов оригинального битмапа.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Имею XML с сложной структурой (CommerceML) и нужно выпарсить некоторые значения оттуда
Сделал такую конструкцию, для добавления данных в базу, вопрос, Правильно ли написан запрос, и если учитывать то, что это цикл, будет ли эффективным...