Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2003.10.23;
Скачать: [xml.tar.bz2];

Вниз

графика и память   Найти похожие ветки 

 
nuflin   (2003-06-20 13:12) [0]

я сделал программу наподобе заливки в паинте но работает очень медленно потому что работает смассивом
как мне сделать чтоб она работала с памятью


 
AlexT1000   (2003-06-20 13:43) [1]

такого быть не может. дело в твоем алгоритме. покажи


 
Fenik   (2003-06-20 19:34) [2]

Массив чего?
Что за память?


 
INCOGNITO   (2003-06-21 01:38) [3]

Как понять фразу "Я сделал программы наподобие заливки в паинте"?
Это типа
Я сварил суп наподобие учебника по математики... Бред абсолютный.
Изложи мыслю толковее!





 
nuflin   (2003-06-21 19:13) [4]

ну я вам просто удивляюсь
вот алгоритм заливки на buildere,а мне надо на delphi
Процедура последовательно просматривает соседние точки,
и если они не залиты, то заливает и добавляет 4
соседние точки в очередь, на рассмотрение. И так пока очередь
не кончится.
На форме достаточно иметь TImage - Image1.

void ImageFill(short x, short y, TColor color) {
// Получим размеры изображения
int imw=Form1->Image1->Width;
int imh=Form1->Image1->Height;
// Выделим памяти для складирования координат, которые еще предстоит залить
int STACK_SIZE=(imw+2)*(imh+2);
short *floodfill_stackx=(short*)malloc(STACK_SIZE*sizeof(short));
short *floodfill_stacky=(short*)malloc(STACK_SIZE*sizeof(short));
if (floodfill_stacky==NULL || floodfill_stackx==NULL) return;
int stack_head=0;
int stack_tail=0;
TColor clr=Form1->Image1->Canvas->Pixels[x][y];
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x][y]=color;
stack_head++;
// Пока не кончится память или точки на изображении
while (stack_head<STACK_SIZE && stack_head>stack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && x<imw && y<imh) {
// Проверим точку справа, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x+1][y]==clr) {
floodfill_stackx[stack_head]=x+1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x+1][y]=color;
stack_head++;
}
// Проверим точку слева, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x-1][y]==clr) {
floodfill_stackx[stack_head]=x-1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x-1][y]=color;
stack_head++;
}
// Проверим точку снизу, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y+1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y+1;
Form1->Image1->Canvas->Pixels[x][y+1]=color;
stack_head++;
}
// Проверим точку сверху, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y-1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y-1;
Form1->Image1->Canvas->Pixels[x][y-1]=color;
stack_head++;
}
}
}
Form1->Image1->Canvas->TextOutA(1,1,IntToStr(stack_head));
// Освободим память
free(floodfill_stacky);
free(floodfill_stackx);
}

void __fastcall TForm1::Button1Click(TObject *Sender) {
Image1->Canvas->Ellipse(20,20,300,200);
( 1,1,0xFF0000)
ну я вам просто удивляюсь
вот алгоритм заливки на buildere,а мне надо на delphi
Процедура последовательно просматривает соседние точки,
и если они не залиты, то заливает и добавляет 4
соседние точки в очередь, на рассмотрение. И так пока очередь
не кончится.
На форме достаточно иметь TImage - Image1.

void ImageFill(short x, short y, TColor color) {
// Получим размеры изображения
int imw=Form1->Image1->Width;
int imh=Form1->Image1->Height;
// Выделим памяти для складирования координат, которые еще предстоит залить
int STACK_SIZE=(imw+2)*(imh+2);
short *floodfill_stackx=(short*)malloc(STACK_SIZE*sizeof(short));
short *floodfill_stacky=(short*)malloc(STACK_SIZE*sizeof(short));
if (floodfill_stacky==NULL || floodfill_stackx==NULL) return;
int stack_head=0;
int stack_tail=0;
TColor clr=Form1->Image1->Canvas->Pixels[x][y];
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x][y]=color;
stack_head++;
// Пока не кончится память или точки на изображении
while (stack_head<STACK_SIZE && stack_head>stack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && x<imw && y<imh) {
// Проверим точку справа, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x+1][y]==clr) {
floodfill_stackx[stack_head]=x+1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x+1][y]=color;
stack_head++;
}
// Проверим точку слева, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x-1][y]==clr) {
floodfill_stackx[stack_head]=x-1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x-1][y]=color;
stack_head++;
}
// Проверим точку снизу, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y+1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y+1;
Form1->Image1->Canvas->Pixels[x][y+1]=color;
stack_head++;
}
// Проверим точку сверху, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y-1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y-1;
Form1->Image1->Canvas->Pixels[x][y-1]=color;
stack_head++;
}
}
}
Form1->Image1->Canvas->TextOutA(1,1,IntToStr(stack_head));
// Освободим память
free(floodfill_stacky);
free(floodfill_stackx);
}

void __fastcall TForm1::Button1Click(TObject *Sender) {
Image1->Canvas->Ellipse(20,20,300,200);
ImageFill(1,1,0xFF0000);
}


 
nuflin   (2003-06-21 19:13) [5]

ну я вам просто удивляюсь
вот алгоритм заливки на buildere,а мне надо на delphi
Процедура последовательно просматривает соседние точки,
и если они не залиты, то заливает и добавляет 4
соседние точки в очередь, на рассмотрение. И так пока очередь
не кончится.
На форме достаточно иметь TImage - Image1.

void ImageFill(short x, short y, TColor color) {
// Получим размеры изображения
int imw=Form1->Image1->Width;
int imh=Form1->Image1->Height;
// Выделим памяти для складирования координат, которые еще предстоит залить
int STACK_SIZE=(imw+2)*(imh+2);
short *floodfill_stackx=(short*)malloc(STACK_SIZE*sizeof(short));
short *floodfill_stacky=(short*)malloc(STACK_SIZE*sizeof(short));
if (floodfill_stacky==NULL || floodfill_stackx==NULL) return;
int stack_head=0;
int stack_tail=0;
TColor clr=Form1->Image1->Canvas->Pixels[x][y];
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x][y]=color;
stack_head++;
// Пока не кончится память или точки на изображении
while (stack_head<STACK_SIZE && stack_head>stack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && x<imw && y<imh) {
// Проверим точку справа, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x+1][y]==clr) {
floodfill_stackx[stack_head]=x+1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x+1][y]=color;
stack_head++;
}
// Проверим точку слева, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x-1][y]==clr) {
floodfill_stackx[stack_head]=x-1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x-1][y]=color;
stack_head++;
}
// Проверим точку снизу, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y+1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y+1;
Form1->Image1->Canvas->Pixels[x][y+1]=color;
stack_head++;
}
// Проверим точку сверху, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y-1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y-1;
Form1->Image1->Canvas->Pixels[x][y-1]=color;
stack_head++;
}
}
}
Form1->Image1->Canvas->TextOutA(1,1,IntToStr(stack_head));
// Освободим память
free(floodfill_stacky);
free(floodfill_stackx);
}

void __fastcall TForm1::Button1Click(TObject *Sender) {
Image1->Canvas->Ellipse(20,20,300,200);
( 1,1,0xFF0000) ну я вам просто удивляюсь
вот алгоритм заливки на buildere,а мне надо на delphi
Процедура последовательно просматривает соседние точки,
и если они не залиты, то заливает и добавляет 4
соседние точки в очередь, на рассмотрение. И так пока очередь
не кончится.
На форме достаточно иметь TImage - Image1.

void ImageFill(short x, short y, TColor color) {
// Получим размеры изображения
int imw=Form1->Image1->Width;
int imh=Form1->Image1->Height;
// Выделим памяти для складирования координат, которые еще предстоит залить
int STACK_SIZE=(imw+2)*(imh+2);
short *floodfill_stackx=(short*)malloc(STACK_SIZE*sizeof(short));
short *floodfill_stacky=(short*)malloc(STACK_SIZE*sizeof(short));
if (floodfill_stacky==NULL || floodfill_stackx==NULL) return;
int stack_head=0;
int stack_tail=0;
TColor clr=Form1->Image1->Canvas->Pixels[x][y];
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x][y]=color;
stack_head++;
// Пока не кончится память или точки на изображении
while (stack_head<STACK_SIZE && stack_head>stack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && x<imw && y<imh) {
// Проверим точку справа, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x+1][y]==clr) {
floodfill_stackx[stack_head]=x+1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x+1][y]=color;
stack_head++;
}
// Проверим точку слева, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x-1][y]==clr) {
floodfill_stackx[stack_head]=x-1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x-1][y]=color;
stack_head++;
}
// Проверим точку снизу, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y+1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y+1;
Form1->Image1->Canvas->Pixels[x][y+1]=color;
stack_head++;
}
// Проверим точку сверху, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y-1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y-1;
Form1->Image1->Canvas->Pixels[x][y-1]=color;
stack_head++;
}
}
}
Form1->Image1->Canvas->TextOutA(1,1,IntToStr(stack_head));
// Освободим память
free(floodfill_stacky);
free(floodfill_stackx);
}

void __fastcall TForm1::Button1Click(TObject *Sender) {
Image1->Canvas->Ellipse(20,20,300,200);
ImageFill(1,1,0xFF0000);
}


 
nuflin   (2003-06-21 19:15) [6]

ну я вам просто удивляюсь
вот алгоритм заливки на buildere,а мне надо на delphi
Процедура последовательно просматривает соседние точки,
и если они не залиты, то заливает и добавляет 4
соседние точки в очередь, на рассмотрение. И так пока очередь
не кончится.
На форме достаточно иметь TImage - Image1.

void ImageFill(short x, short y, TColor color) {
// Получим размеры изображения
int imw=Form1->Image1->Width;
int imh=Form1->Image1->Height;
// Выделим памяти для складирования координат, которые еще предстоит залить
int STACK_SIZE=(imw+2)*(imh+2);
short *floodfill_stackx=(short*)malloc(STACK_SIZE*sizeof(short));
short *floodfill_stacky=(short*)malloc(STACK_SIZE*sizeof(short));
if (floodfill_stacky==NULL || floodfill_stackx==NULL) return;
int stack_head=0;
int stack_tail=0;
TColor clr=Form1->Image1->Canvas->Pixels[x][y];
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x][y]=color;
stack_head++;
// Пока не кончится память или точки на изображении
while (stack_head<STACK_SIZE && stack_head>stack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && x<imw && y<imh) {
// Проверим точку справа, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x+1][y]==clr) {
floodfill_stackx[stack_head]=x+1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x+1][y]=color;
stack_head++;
}
// Проверим точку слева, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x-1][y]==clr) {
floodfill_stackx[stack_head]=x-1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x-1][y]=color;
stack_head++;
}
// Проверим точку снизу, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y+1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y+1;
Form1->Image1->Canvas->Pixels[x][y+1]=color;
stack_head++;
}
// Проверим точку сверху, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y-1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y-1;
Form1->Image1->Canvas->Pixels[x][y-1]=color;
stack_head++;
}
}
}
Form1->Image1->Canvas->TextOutA(1,1,IntToStr(stack_head));
// Освободим память
free(floodfill_stacky);
free(floodfill_stackx);
}

void __fastcall TForm1::Button1Click(TObject *Sender) {
Image1->Canvas->Ellipse(20,20,300,200);
( 1,1,0xFF0000)
ну я вам просто удивляюсь
вот алгоритм заливки на buildere,а мне надо на delphi
Процедура последовательно просматривает соседние точки,
и если они не залиты, то заливает и добавляет 4
соседние точки в очередь, на рассмотрение. И так пока очередь
не кончится.
На форме достаточно иметь TImage - Image1.

void ImageFill(short x, short y, TColor color) {
// Получим размеры изображения
int imw=Form1->Image1->Width;
int imh=Form1->Image1->Height;
// Выделим памяти для складирования координат, которые еще предстоит залить
int STACK_SIZE=(imw+2)*(imh+2);
short *floodfill_stackx=(short*)malloc(STACK_SIZE*sizeof(short));
short *floodfill_stacky=(short*)malloc(STACK_SIZE*sizeof(short));
if (floodfill_stacky==NULL || floodfill_stackx==NULL) return;
int stack_head=0;
int stack_tail=0;
TColor clr=Form1->Image1->Canvas->Pixels[x][y];
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x][y]=color;
stack_head++;
// Пока не кончится память или точки на изображении
while (stack_head<STACK_SIZE && stack_head>stack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && x<imw && y<imh) {
// Проверим точку справа, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x+1][y]==clr) {
floodfill_stackx[stack_head]=x+1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x+1][y]=color;
stack_head++;
}
// Проверим точку слева, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x-1][y]==clr) {
floodfill_stackx[stack_head]=x-1;
floodfill_stacky[stack_head]=y;
Form1->Image1->Canvas->Pixels[x-1][y]=color;
stack_head++;
}
// Проверим точку снизу, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y+1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y+1;
Form1->Image1->Canvas->Pixels[x][y+1]=color;
stack_head++;
}
// Проверим точку сверху, если она не залита, то зальем
if (Form1->Image1->Canvas->Pixels[x][y-1]==clr) {
floodfill_stackx[stack_head]=x;
floodfill_stacky[stack_head]=y-1;
Form1->Image1->Canvas->Pixels[x][y-1]=color;
stack_head++;
}
}
}
Form1->Image1->Canvas->TextOutA(1,1,IntToStr(stack_head));
// Освободим память
free(floodfill_stacky);
free(floodfill_stackx);
}

void __fastcall TForm1::Button1Click(TObject *Sender) {
Image1->Canvas->Ellipse(20,20,300,200);
ImageFill(1,1,0xFF0000);
}


 
Mihey   (2003-06-21 20:04) [7]

Ну ты даёшь. Естественно всё будет медленно по той причине, что обращение к Form1.Image1.Canvas.Pixels[x,y] офигенно медленное и тормознутое.

Выход из ситуации:

1. Использовать TBitMap.ScanLine. Это сложно, но можно. Инфа здесь: http://www.efg2.com/Lab/ImageProcessing/Scanline.htm.

2. Использовать Graphic32. Это только кажется, что сложно. На самом деле всё очень подобно простой работе с изображением, с те мотличием, что обращение к Pixel или PixelS (это варианты для Graphic32) не тормозит.


 
Fenik   (2003-06-21 21:24) [8]

А что, Canvas.FloodFill уже не рулит?


 
Mihey   (2003-06-21 21:51) [9]

2 Fenik:

Алгоритм всё ранво хорошо бы знать для того, чтобы сделать, например, работу с текстурами.


 
Fenik   (2003-06-21 22:44) [10]

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


 
Mihey   (2003-06-21 23:53) [11]

2 Fenik:

Ссылка не работает, потому что форум выделил её вместе с точкой на конце.


 
Fenik   (2003-06-22 00:03) [12]

Кстати, на делфи я не видел реализацию заливки. Хотя думаю это не сложно. Сложнее - это оптимизация...


 
Mihey   (2003-06-22 00:45) [13]

2 Fenik:

Действительно, в реализации канвы функция FloodFill реализует ExtFloodFill ил Gdi32.


 
Fenik   (2003-06-22 01:15) [14]

Я как-то сам хотел писать, да потом необходимость отпала. Но скоро она наверное снова возникнет, и придётся писать.. Так что, буду думать как.

Для текстур есть такая идея:
1. Создать однобитный битмап для маски.

2. В цикле (или в рекурсии) просматривать соседние точки: если точка такого же цвета, то
а). закрашиваем её на битмапе для маски;
б). вставляем её в очередь для обработки (проверки её соседей);
При проверке соседей также смотрим на маску: если точка закрашена, значит её уже обработали и она на не нужна.

3. Работаем с маской как хотим.. кто во что горазд...


В пунке 2 можно проверять не на цвет, а на яркость, контраст и т.п. Можно сделать инструмент "Волшебная палочка", как в крутых редакторах, для выделения однотипной области. Тут просто простор для фантазии, по какому типу выделять или заливать область.. Всё упирается в алгоритм обхода точек. Нужно сделать оптимально быстрый цикл.



Страницы: 1 вся ветка

Форум: "Media";
Текущий архив: 2003.10.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.009 c
3-74028
alex25
2003-10-03 13:18
2003.10.23
множественное like


14-74427
Igor_thief
2003-10-04 10:02
2003.10.23
MDI


1-74159
Sasha M
2003-10-10 16:36
2003.10.23
Компонент вроде DBCtrlGrid, только без DB


1-74311
Tihomirov
2003-10-05 21:49
2003.10.23
Графика в DLL


1-74255
WolfGun
2003-10-13 12:34
2003.10.23
Массив полигонов...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский