Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.05.2011, 19:46   #1
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
Вопрос Делаем Paint

Задание сделать подобие Paint'a, т.е. мини графический редактор. Загрузка изображений, рисование каракуль на них, сохранение.

Вопрос - на чём лучше рисовать(на каком компоненте) и есть ли какие нибудь подводные камни(если кто уже с подобным сталкивался). Буду рад как перечню ссылок на статьи, так и корявому ответу в двух словах(тока не грубых и не заставляющих гуглить)).

Заранее спасибо.

Последний раз редактировалось Ksardas13; 09.05.2011 в 15:37.
Ksardas13 вне форума Ответить с цитированием
Старый 08.05.2011, 22:21   #2
}|{opa KopHeB
Пользователь
 
Регистрация: 14.01.2011
Сообщений: 23
По умолчанию

Вот рисовалка собранная в msvc 6. Поглядите, быть может натолкнёт на какие-то мысли. ТыЦ
}|{opa KopHeB вне форума Ответить с цитированием
Старый 09.05.2011, 01:12   #3
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
По умолчанию

Во класс, спасибо, пригодится.

Кстати, ещё интересный вопрос, как реализовать кнопки "отмена"-"возврат". Ну допустим отмена/возврат в одно действие ещё можно - просто над рисунком сделать ещё один невидимый холст, рисовать текущее действие на нём, если пользователь перешёл к следующему действию - старое кидаем на основной рисунок, новое опять рисуем на невидимом слою. Можно даже сделать три таких невидимых слоя, что увеличит возможность откатов до трёх.

Но как подобное реализовано скажем в Фотошопе, где количество отмен гораздо больше? Кто нибудь в курсе?
Ksardas13 вне форума Ответить с цитированием
Старый 09.05.2011, 12:30   #4
}|{opa KopHeB
Пользователь
 
Регистрация: 14.01.2011
Сообщений: 23
По умолчанию

Мне в голову приходит следующее:

Поскольку изображение есть совокупность пикселей, а сам пиксель может быть только 1 цвета в единицу времени, то можем представить "полотно для рисования" в виде двумерного массива в ячейки которого записываем цвет пикселя. Вдобавок прикрутить это к стеку (FILO) и записывать в него "снимки" экрана в момент начала (напр. OnMouseDown) рисования и в конце (OnMouseUp).

Надеюсь понятно описал...
ЗЫ На практике не применял, исключительно полёт мысли
}|{opa KopHeB вне форума Ответить с цитированием
Старый 09.05.2011, 12:44   #5
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
По умолчанию

Ну если я тебя правильно понял, то просто фоткать экран в момент касания его кистью. Потом когда кисть отрывается от экрана и вдруг пользователь жахает по кнопке Отмена - заменять холст на холст из фотки.
Тоже можно, но опять же будем хранить в памяти(или где нибудь за экраном) кучу снимков(по количеству возможных откатов). А если вспомнить что в Фотошопе ещё есть и такая штука как слои... Даже представить страшно сколько фигни они хранят за пределами экрана, если Фотошоп позволяет отменять до 30 действий(ну или где то так)...
Ksardas13 вне форума Ответить с цитированием
Старый 09.05.2011, 15:21   #6
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
По умолчанию

О, У МЕНЯ ПОЛНОЦЕННЫЙ ВОПРОС!!
Как реализовать заливку?
Есть такой вариант http://www.codenet.ru/progr/video/alg/alg5.php, но может есть способ полегче?
Ksardas13 вне форума Ответить с цитированием
Старый 09.05.2011, 15:34   #7
}|{opa KopHeB
Пользователь
 
Регистрация: 14.01.2011
Сообщений: 23
По умолчанию

"Пример показывает один из самых простых и эффективных способов заливки."

Проще взять готовое
}|{opa KopHeB вне форума Ответить с цитированием
Старый 09.05.2011, 15:37   #8
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
По умолчанию

Просто рисую кок раз на канве компонента Timage. Ох боюсь глючить будет. Ладно, щас попробую попробывать.))

Если кому пригодится, вот кое что нашёл:
http://www.ad.cctpu.edu.ru/Personal/...ill%5CFill.htm

Последний раз редактировалось Ksardas13; 09.05.2011 в 15:47.
Ksardas13 вне форума Ответить с цитированием
Старый 09.05.2011, 18:45   #9
Ksardas13
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 120
По умолчанию

Кто ради прикола(хотя пока я пользюсь этой процедурой и быстродействие ох как хочется поднять) поможет оптимизировать следующий бред:
Код:
//Заливка области на Form1->Image1_pic->Canvas.
//Передаём координаты пикселя, по которому кликнули, цвет заливки и цвет пикселя,
//по которому кликнули соответственно.
//Перед вызовом необходимо чтобы(Form1->Image1_pic->Canvas->Pixels[X][Y]!=new_color)! Иначе зациклимся.
void filling_area(int X,int Y,TColor new_color,TColor old_color)
{
TColor buf_color;int buf_x,left_x,right_x,i;//Переменные.
Form1->Image1_pic->Canvas->Pixels[X][Y]=new_color;//Закрасили пиксель новым цветом!
buf_x=X;//!!!!!!!!!!Взяли значение Х, щас пойдём влево.!!!!!!!!!!
while(1)
  {if ((buf_x)==0) {left_x=buf_x;break;}//значит дошли до края!!!!!!!!!если нет, идём дальше.
   buf_x=buf_x-1;//уменьшение х, т.е. передвижение влево.
   buf_color=Form1->Image1_pic->Canvas->Pixels[buf_x][Y];//запрос цвета в нашей новой точке.
   if (buf_color==old_color) Form1->Image1_pic->Canvas->Pixels[buf_x][Y]=new_color;//Заливаааем!
    else {left_x=buf_x;break;}}
buf_x=X;//!!!!!!!!!!Снова взяли значение Х, щас пойдём вправо.!!!!!!!!!!
while(1)
  {if ((buf_x)==865) {right_x=buf_x;break;}//значит дошли до края! если нет, идём дальше.
   buf_x=buf_x+1;//увеличение х, т.е. передвижение вправо.
   buf_color=Form1->Image1_pic->Canvas->Pixels[buf_x][Y];//запрос цвета в нашей новой точке.
   if (buf_color==old_color) Form1->Image1_pic->Canvas->Pixels[buf_x][Y]=new_color;//Заливаааем!
    else {right_x=buf_x;break;}}
//!!!!!!!!!!Эта часть проверяет выше и ниже лежащие писклы на цвет и вызывает функцию!!!!!!!!!!
for (i=left_x+1;i<right_x;i++)// идём слева направо.
  {
   if (Y!=505) {buf_color=Form1->Image1_pic->Canvas->Pixels[i][Y+1];//запрос цвета строкой ниже, если это не последняя строка
                if (buf_color==old_color) filling_area(i,Y+1,new_color,old_color);}//если цвет не тот, заливаем тем!
   if (Y!=0)  {buf_color=Form1->Image1_pic->Canvas->Pixels[i][Y-1];//запрос цвета строкой выше, если это не последняя строка
               if (buf_color==old_color) filling_area(i,Y-1,new_color,old_color);}//если цвет не тот, заливаем тем!
  }
}
И за одно вопрос - как закинуть в эту процедуру компонент image1, чтобы не вызывать каждый раз его через Form1->Image1...?

ps: 865 и 505 это габариты Image1_pic

Последний раз редактировалось Ksardas13; 09.05.2011 в 18:55.
Ksardas13 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Делаем фреймы) Lyubov1990 HTML и CSS 4 20.01.2011 19:31
Банкомат делаем.. Andrey_andrey Microsoft Office Access 1 24.05.2009 16:18
делаем код программы легче XFilippowX Общие вопросы Delphi 4 15.02.2009 11:20
Paint Артэс Win Api 4 30.11.2008 02:09
paint ben95 Общие вопросы Delphi 1 30.03.2008 09:27