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

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

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

Delphi.int.ru Expert

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

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

#   

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


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

Подробнее »



Вопрос # 4 810

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

Приветствую, уважаемые эксперты!
Хотелось бы реализовать следующее.
Имеется JPG изображение карты одной из областей России, с выделенными разными цветами районами внутри области.
Необходимо при наведении мыши на наименование района помещенное в Label с периодичностью 1 раз в сек. менять цвет района на clRed.
Во наговорил...
Наверно попроще, подскажите, как в Image при загруженном JPG изменить цвет нескольких пикселей, если знаешь их цвет.
С уважением
Al_Sha

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

Вопрос задал: Al_Sha (статус: Посетитель)
Вопрос отправлен: 12 декабря 2010, 20:33
Состояние вопроса: открыт, ответов: 1.

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

Здравствуйте, Al_Sha!
Расскажу, как делается, что бы при наведении мышки можно было узнать, что за район. Многие советуют делать хитрые условие, находить замкнутые многоугольники и вспоминать "школьную" геометрию. На самом деле все делается проще. Открываем карту в Paint и сделаем из нее маску. Для этого затираем название, а каждый район закрашиваем уникальным цветом. Цвета могут быть неотличимы на глаз, главное, что бы на карте не было двух разных регионов с одинаковым цветом (в целом, если припустить, что район области может состоять с двух или трех частей, то нужно каждую часть закрасить одним цветом, а можно и разными - появиться некая гибкость). Теперь полученную карту сохраняем в bmp. В jpg можно сохранить, но нужно быть осторожным - может повреждаться цвет. В GIF - кол-во цветов обычно уменьшается до 256, поэтому если выбрать цвета правильно, то можно сэкономить. Можно карту сохранить в bmp, но с размерами в 2 или 4 раза меньше.

Теперь возвращаемся к программе. Кроме основной карты, нужно будет ещё грузить карту-маску, но в память (в TBitmap), видеть пользователю её не нужно. Теперь, когда водим мышкой по карте, проверяем по карте маске цвет. Так как цвета для каждого района уникальные - то мы можем составить массив соответствий цвет-название. Если маску уменьшали, то координаты естественно нужно будет пропорционально уменьшить.

Теперь вернемся к закраске. Если у нас есть такая карта-маска, то делать закраску просто - нужно просто пробежаться по карте-маске, посмотреть, где совпадает цвет с цветом текущего района и подкрасить. Конечно, это все можно хорошо оптимизировать, если для каждого района найти такой прямоугольник, в который он попадает, тогда двойной цикл для поиска будет работать очень быстро.

Теперь последние штрихи. Рисовать на TImage - плохо, потому что медленно. Лучше рисовать в TBitmap, а потом переносить одним движением (то есть вызовом метода CopyRect у Canvas или подобного). При этом, если держать в памяти две картинки, то можно рисовать закрашенный регион только один раз при входе в него, а потом, пока мышка находиться в нем - просто использовать готовый.
Но есть ещё одна проблема. Рисовать на канве, в которую загружен jpeg - нельзя. Не даст:) Будет говорить, что canvas только readonly. Поэтому нужно все таки грузить в память, а потом отрисовывать.

Полезные ссылки:
http://www.delphisources.ru/pages/faq/base/jpeg_to_bmp.html
http://www.delphisources.ru/pages/faq/base/bmp_to_jpeg.html
http://www.delphisources.ru/pages/faq/base/copyrect_anim.html

Если будут затруднения - пишем в минифорум, разберем:)

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 12 декабря 2010, 22:29
Оценка за ответ: 5

Комментарий к оценке: Спасибо, итнформация для меня полезная, будем разбираться...
С уважением Al_Sha

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

Всего сообщений: 5; последнее сообщение — 13 декабря 2010, 07:19; участников в обсуждении: 3.
prorok-kane

prorok-kane (статус: Посетитель), 12 декабря 2010, 21:48 [#1]:

Можно взять определенную область соответствующую названию и проходится по поверхности цвета выбранного района и закрасить красным, через секунду закрасить цветом по дефулту и покругу.
Задай заранее области выделения соответствующей области и проверяй еще цвета!
prorok-kane

prorok-kane (статус: Посетитель), 12 декабря 2010, 21:51 [#2]:

for i:=nach_rayonaX to konec_rayonaX do
for j:=nach_rayonaY to konec_rayonaY do
if (Image1.Canvas.Pixels[i,j]=current_color)
then Image1.Canvas.Pixels[i,j]:=red;
for i:=nach_rayonaX to konec_rayonaX do
for j:=nach_rayonaY to konec_rayonaY do
if (Image1.Canvas.Pixels[i,j]=red;
then Image1.Canvas.Pixels[i,j]:=current_color;
Только главное, чтобы красный нигде не встречался!
В RGB это реально!
Вадим К

Вадим К (статус: Академик), 12 декабря 2010, 21:56 [#3]:

Вот только работать это будет меееедленно, если вообще будет работать:)
Галочка "подтверждения прочтения" - вселенское зло.
prorok-kane

prorok-kane (статус: Посетитель), 12 декабря 2010, 21:57 [#4]:

Период меняем за счет таймера!
Timer1.interval:=1000; //одна секунда

procedure ontimer
begin
if n=0
then
begin
//пихаем процедуру закрашивания красным
n:=1;
end
else begin
//процедура выбранного цвета
n:=0;
end;
end;
С производительностью действительно возможны проблемы!
Al_Sha

Al_Sha (статус: Посетитель), 13 декабря 2010, 07:19 [#5]:

Спасибо всем откликнувшимся.
С уважением Al_Sha

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

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