![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
графика и память
nuflin © (2003-06-20 13:12:00)
я сделал программу наподобе заливки в паинте но работает очень медленно потому что работает смассивом
как мне сделать чтоб она работала с памятью
Fenik (2003-06-22 01:15:00) [1]
Я как-то сам хотел писать, да потом необходимость отпала. Но скоро она наверное снова возникнет, и придётся писать.. Так что, буду думать как.
Для текстур есть такая идея:
1. Создать однобитный битмап для маски.
2. В цикле (или в рекурсии) просматривать соседние точки: если точка такого же цвета, то
а). закрашиваем её на битмапе для маски;
б). вставляем её в очередь для обработки (проверки её соседей);
При проверке соседей также смотрим на маску: если точка закрашена, значит её уже обработали и она на не нужна.
3. Работаем с маской как хотим.. кто во что горазд...
В пунке 2 можно проверять не на цвет, а на яркость, контраст и т.п. Можно сделать инструмент "Волшебная палочка", как в крутых редакторах, для выделения однотипной области. Тут просто простор для фантазии, по какому типу выделять или заливать область.. Всё упирается в алгоритм обхода точек. Нужно сделать оптимально быстрый цикл.
Mihey (2003-06-22 00:45:00) [2]
2 Fenik:
Действительно, в реализации канвы функция FloodFill реализует ExtFloodFill ил Gdi32.
Fenik (2003-06-22 00:03:00) [3]
Кстати, на делфи я не видел реализацию заливки. Хотя думаю это не сложно. Сложнее - это оптимизация...
Mihey (2003-06-21 23:53:00) [4]
2 Fenik:
Ссылка не работает, потому что форум выделил её вместе с точкой на конце.
Fenik (2003-06-21 22:44:00) [5]
Я согласен, что надо знать алгоритм и использовать его через TBitmap.ScanLine. Кстати, ссылка не работает.
Но автору вопроса нужна заливка цветом, как я понял, поэтому FloodFill - имхо лучший выход.
Mihey (2003-06-21 21:51:00) [6]
2 Fenik:
Алгоритм всё ранво хорошо бы знать для того, чтобы сделать, например, работу с текстурами.
Fenik (2003-06-21 21:24:00) [7]
А что, Canvas.FloodFill уже не рулит?
Mihey (2003-06-21 20:04:00) [8]
Ну ты даёшь. Естественно всё будет медленно по той причине, что обращение к Form1.Image1.Canvas.Pixels[x,y] офигенно медленное и тормознутое.
Выход из ситуации:
1. Использовать TBitMap.ScanLine. Это сложно, но можно. Инфа здесь: http://www.efg2.com/Lab/ImageProcessing/Scanline.htm.
2. Использовать Graphic32. Это только кажется, что сложно. На самом деле всё очень подобно простой работе с изображением, с те мотличием, что обращение к Pixel или PixelS (это варианты для Graphic32) не тормозит.
nuflin (2003-06-21 19:15:00) [9]ну я вам просто удивляюсь
вот алгоритм заливки на 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_headstack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && xCanvas->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_headstack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && xCanvas->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:00) [10]ну я вам просто удивляюсь
вот алгоритм заливки на 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_headstack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && xCanvas->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_headstack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && xCanvas->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:00) [11]ну я вам просто удивляюсь
вот алгоритм заливки на 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_headstack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && xCanvas->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_headstack_tail) {
x=floodfill_stackx[stack_tail];
y=floodfill_stacky[stack_tail];
stack_tail++;
if (x>=0 && y>=0 && xCanvas->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);
}
INCOGNITO (2003-06-21 01:38:00) [12]
Как понять фразу "Я сделал программы наподобие заливки в паинте"?
Это типа
Я сварил суп наподобие учебника по математики... Бред абсолютный.
Изложи мыслю толковее!
Fenik (2003-06-20 19:34:00) [13]
Массив чего?
Что за память?
AlexT1000 (2003-06-20 13:43:00) [14]
такого быть не может. дело в твоем алгоритме. покажи