Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 403

/ вопрос открыт /

Здравствуйте. Для выделения точек на канве, я выделяю их с помощью процедурки: DrawFocusRect. Однако при движении прямоугольника проходиться перерисовывать полностью все, поэтому изображение мелькает. Если при движении сохранять предыдущую точку и потом переривывать с помощью: FrameRect и DrawFocusRect, то рисунок частично стирается. Думаю нужно сохранять как-то прямоугольник "полностью" (по массиву линий), но обращение к отдельному пикселю слишком медленное. Что лучше применить в данном случае?

SMaks Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: SMaks (статус: 1-ый класс)
Вопрос отправлен: 13 марта 2007, 04:01
Состояние вопроса: открыт, ответов: 3.

Ответ #1. Отвечает эксперт: Роман

Здравствуйте, SMaks!Я в таких случаях использыю вспомогательные слои т.е кпримеру есть расунок фона и нужно перемещять по нему какойлибо об'ект:создаём bg_fon:TImage;грузим в него фоновую картинку,ещё один bg_work:TImage,далее в цикле анимации c помощью copyrect переношу bg_fon на bg_work,рисую на bg_work что надо и copyrect на видимый canvas,и никаких мерцаний нет.И если есть желание посмотрите на delphiworld.narod.ru/_graphic_.html(Графика и Игры).Кстати можно воспользоватся графической библиотекой SpriteUtils с http://www.delphikingdom.com.

Ответ отправил: Роман (статус: 5-ый класс)
Время отправки: 13 марта 2007, 04:52
Оценка за ответ: 5

Комментарий к оценке: В моем случае полностью прямоугольник копировать не нужно, только 4 линии, а как это сделать максимально быстро?

Ответ #2. Отвечает эксперт: Вадим К

Если вам нужен только прямоугольник выделения, то советую воспользоваться режимим карандаша xor. В результате никаких дополнительных манипуляций.
как сделать.
Image1.Canvas.pen.mode:=pmXOR;//Кажеться так
//рисуем прямоугольник.
//он рисуется поверх старого!
//благодаря режиму ксор он сотрётся
//терерь сдвигаем координаты и снова рисуем прямоугольник.

То есть, хотя мы рисуем два прямоугольника, скорость приличная.Испытано много раз. Здесьмы используем то, что A xor B xor B = A

Предупрежу вопрос о быстром доступе к пикселям. Погуглите на тему ScanLine

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 13 марта 2007, 11:30
Оценка за ответ: 4

Комментарий к оценке: Пробовал, мелькает сильно.

Ответ #3. Отвечает эксперт: Новаковский Юрий Аврамович

Здравствуйте, SMaks!

Создайте переменную
var BitMap:TBitMap;

Инициализируйте ее
BitMap := TBitMap.Create;

Копируйте канву с Вашего имиджа
BitMap.Canvas.Assing(Image1.Canvas);

Чевото делаете с изображением
BitMap.Canvas.Pixels[100,44]:=clRed;
.....
.....
При этом никаких перерисовок не происходит т.к.
BitMap не виден и все операции с ним не затрагивают графическую подсистему.
Для этого он и существует.

Возвращаете канву на место
Image1.Canvas.Assing(BitMap.Canvas);
Вот тут и будет перерисовка ОДНА.
BitMap.Free;

Все! Удачи!

Ответ отправил: Новаковский Юрий Аврамович (статус: 4-ый класс)
Время отправки: 13 марта 2007, 12:22
Оценка за ответ: 4


Мини-форум вопроса

Всего сообщений: 3; последнее сообщение — 15 марта 2007, 14:02; участников в обсуждении: 3.
Вадим К

Вадим К (статус: Академик), 13 марта 2007, 15:19 [#1]:

На самом деле все эксперты забыли сказать одно. Почему происходят мерцания. А потому, что прорисовок две, даже учитывая вышесказаное. Вы ведь рисуете тогда, когда вы хотите, а не когда виндовс готова. Делайте так.
В обработчиках движения мыши, где вы изменяете положение курсора просто запоминайте координаты. А саму прорисовку делайте в OnPaint (в случае PaintBox)., Что бы компоненту сказать "перерисуйся" отправляем ему такое сообщение SendMessage(PaintBox1.handle,WM_PAINT,0,0);
Галочка "подтверждения прочтения" - вселенское зло.
Роман

Роман (статус: 5-ый класс), 14 марта 2007, 04:36 [#2]:

Вообщето справедливо указано про WM_PAINT он это актуально только в случае если мы рисуем на canvas формы(TForm),а если используется Тpaintbox или Тimage то указывать им на необходимость перерисовки ненужно так как событие onPaint генерируется windozoй автоматически при необходимости их перерисовки.Вот,гдето так...
SMaks

SMaks (статус: 1-ый класс), 15 марта 2007, 14:02 [#3]:

Вадим К: Пришлось все-таки от сохранения выделения отказаться, и применить именно это метод, т.к. обновление рисунка ограничено обновлением экрана, итак все работает на ура.
И спасибо что указал на сообщение WM_PAINT, учту при разработке графических компонент.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:27
Выполнено за 0.03 сек.