Форум: "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.01 c