Рисование линий, прямоугольников...
Вот взялся писать графический векторные редактор. Все вроде бы ничего, только появилась одна назойливая проблема. Когда пользователь рисеут какую-либо фигуру(линию, прямоугольник, окружность), фигура "ползет" за мышкой, т.е. расширяется. Проблема состоит в том, что мне пришлось перерисовывать окно каждый раз, когда пользователь двинет мышью в режиме рисования. А, глядя, на другие приложения, подобные моему, мне становится обидно, что у меня так долго рисуется изображене, т.е. если подергать мышью получится такой эффект - изображение ползет, перерисовываясь...
Может быть есть какие-то сопособы опитимизировать это дело?:confused:
А остальное зависит от среды: если Visual Basic, то там как ни странно с этим проблем не возникает.
А если С++ - советую написать или написать свой собственый компонен для аботы с графикой, или - пользоваться вышеприведенной функцией
Я тоже увлекаюсь написанием графическихх приложений, у тебя что за среда?
Про существование bitblt я знаю, т.к. её использую... Вернее не её, а аналог Graphics.DrawImage(bmp, pictureBox1.ClientRectangle), т.к. пишу на C#(Среда Microsoft Visual Studio 2005)
Есть у меня некоторое изображение, созданное по некоторым правилам. Оно хранится в pictureBox. Ну, или, говоря простым языком в bmp-шке.
В случае события OnPaint, относящегося к нашему pictureBox происхоит копирование образа нашей бмпешки на экран. Здесь все ясно.
Мне нужно сделать так, чтобы пользователь мог рисовать линии(прямоугольники, окружности, ...). Поясню как это реализуется у меня: отслеживаются все события MouseMove в области pictureBox(в области... относящиеся к pictureBox); если нажата левая кнопка мыши, линия, рисующаяся от относительного центра, показывается пользователю. Получается эффект перетаскивания "конца" линии. Когда пользователь отпускает кнопку мыши, линия рисуется и больше не бегает за мышькой.
Вопрос: как это сделать без лишних накладных расходов?
Моя задумка состоит в следующем. Как только приходит MouseMove и кнопка нажата мы загружаем образ из памяти и отрисовываем линию на pictureBox. При этом не портится образ. Понятно почему). ... И так далее до тех пор пока пользователь не отпустит кнопку мыши. При постулении сообщения DownMouse(вроде такое) фиксируем линию в образе после чего показываем получившийся образ.
Вроде бы ничего... С первого взгляда. Но у меня почему-то все это делается медленно. В случае с окружностью при быстром перемещении курсора возникает жуткий эффект концентрических окружностей)))
:confused:
Чтобы меньше всего ресурсов требовалось, я очень советую разработать свой компонент, я только так и работаю.
А ты попробуй рисовать методом XOR линии - должно получиться и не тормозить...
Двойная буферизация. Рисуешь в бэк-буфере, переключаешь (визуализируешь), обнуляешь старый буфер и по-новой.
Цитата: Lerkin
Двойная буферизация. Рисуешь в бэк-буфере, переключаешь (визуализируешь), обнуляешь старый буфер и по-новой.
Достаточно для компонента, на котором лежить PaintBox, установить свойство DoubleBuffering в True, и компонент сам будет заниматься переключением буферов. Если под PaintBox только форма, кинь его на TPanel.
P.S. Свойство DoubleBuffering можно выставить только в коде, например, при создании окна.
Цитата: Petya!
А ты попробуй рисовать методом XOR линии - должно получиться и не тормозить...
Не получится. В шарпе нет такой возможности(если б была, не спрашивал бы :) )
Цитата: Sagittarius
Я так понял, автор использует Delphi или Builder.
неа, не дельфи и не булдер :)
Цитата: s((r1pt
... т.к. пишу на C#(Среда Microsoft Visual Studio 2005) ...
:D
Пример:
using System;
using System.Windows.Forms;
namespace WindowsApplication1
{
/// <summary>
/// Summary description for MyPanel.
/// </summary>
public class MyPanel:System.Windows.Forms.Panel
{
public MyPanel()
{
this.SetStyle(ControlStyles.DoubleBuffer,true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);
}
}
}
Вряд ли стоит писать в шарпе вещь, критичную к скорости.