Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.10.23;
Скачать: CL | DM;

Вниз

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

 
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 вся ветка

Текущий архив: 2003.10.23;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.021 c
1-74185
:)
2003-10-10 12:22
2003.10.23
:)


7-74486
Delf
2003-08-08 11:47
2003.10.23
Как програмно выключить/включить монитор в W2k


1-74226
Tommy
2003-10-08 15:06
2003.10.23
nado 4tobi v Gride pravilno visve4ivalis gre4ekie bukvi...


1-74178
Berezne
2003-10-13 17:42
2003.10.23
Ячейки в DBGrid


14-74382
Knight
2003-10-02 18:49
2003.10.23
Как вы относитесь к журналу Хакер?