Bitmap/Flood fill: Difference between revisions

Content added Content deleted
(→‎{{header|Processing Python mode}}: refactored image(img... to show() added an image_file global)
(Added solution for Action!)
Line 8: Line 8:
[[Image:Unfilledcirc.png|128px|thumb|right]]
[[Image:Unfilledcirc.png|128px|thumb|right]]
'''Testing''': the basic algorithm is not suitable for ''truecolor'' images; a possible test image is the one shown on the right box; you can try to fill the white area, or the black inner circle.
'''Testing''': the basic algorithm is not suitable for ''truecolor'' images; a possible test image is the one shown on the right box; you can try to fill the white area, or the black inner circle.

=={{header|Action!}}==
In the following solution a simple implementation of queue has been used.
{{libheader|Action! Bitmap tools}}
<lang Action!>INCLUDE "H6:RGBCIRCL.ACT" ;from task Midpoint circle algorithm

RGB black,white,yellow,blue

TYPE PointB=[BYTE px,py]

TYPE Queue=[CARD qfront,qrear,capacity,qdata]

PROC QueueInit(Queue POINTER q)
DEFINE MAXSIZE="500"
CARD ARRAY a(MAXSIZE)

q.qfront=0
q.qrear=0
q.capacity=MAXSIZE
q.qdata=a
RETURN

BYTE FUNC IsQueueEmpty(Queue POINTER q)
IF q.qfront=q.qrear THEN
RETURN (1)
FI
RETURN (0)

PROC QueuePush(Queue POINTER q PointB POINTER p)
CARD rear
PointB POINTER tmp

rear=q.qrear+1
IF rear=q.capacity THEN
rear=0
FI
IF rear=q.qfront THEN
Break()
FI
tmp=q.qdata+q.qrear*2
tmp.px=p.px
tmp.py=p.py
q.qrear=rear
RETURN

PROC QueuePop(Queue POINTER q PointB POINTER p)
PointB POINTER tmp

IF IsQueueEmpty(q) THEN
Break()
FI
tmp=q.qdata+q.qfront*2
p.px=tmp.px
p.py=tmp.py
q.qfront==+1
IF q.qfront=q.capacity THEN
q.qfront=0
FI
RETURN

PROC DrawImage(RgbImage POINTER img BYTE x,y)
RGB POINTER ptr
BYTE i,j

ptr=img.data
FOR j=0 TO img.h-1
DO
FOR i=0 TO img.w-1
DO
IF RgbEqual(ptr,yellow) THEN
Color=1
ELSEIF RgbEqual(ptr,white) THEN
Color=2
ELSEIF RgbEqual(ptr,blue) THEN
Color=3
ELSE
Color=0
FI
Plot(x+i,y+j)
ptr==+RGBSIZE
OD
OD
RETURN

PROC FloodFill(RgbImage POINTER img BYTE x0,y0 RGB POINTER col)
Queue q
RGB c,tmp
PointB p

GetRgbPixel(img,x0,y0,c)
IF RgbEqual(c,col) THEN
RETURN
FI
p.px=x0 p.py=y0
QueueInit(q)
QueuePush(q,p)
WHILE IsQueueEmpty(q)=0
DO
QueuePop(q,p)
x0=p.px y0=p.py

GetRgbPixel(img,x0,y0,tmp)
IF RgbEqual(tmp,c) THEN
SetRgbPixel(img,x0,y0,col)

IF x0>0 THEN
GetRgbPixel(img,x0-1,y0,tmp)
IF RgbEqual(tmp,c) THEN
p.px=x0-1 p.py=y0
QueuePush(q,p)
FI
FI
IF x0<img.w-1 THEN
GetRgbPixel(img,x0+1,y0,tmp)
IF RgbEqual(tmp,c) THEN
p.px=x0+1 p.py=y0
QueuePush(q,p)
FI
FI
IF y0>0 THEN
GetRgbPixel(img,x0,y0-1,tmp)
IF RgbEqual(tmp,c) THEN
p.px=x0 p.py=y0-1
QueuePush(q,p)
FI
FI
IF y0<img.h-1 THEN
GetRgbPixel(img,x0,y0+1,tmp)
IF RgbEqual(tmp,c) THEN
p.px=x0 p.py=y0+1
QueuePush(q,p)
FI
FI
FI
OD
RETURN

PROC Main()
RgbImage img
BYTE CH=$02FC,size=[40]
BYTE ARRAY ptr(4800)
BYTE n
INT x,y
RGB POINTER col

Graphics(7+16)
SetColor(0,13,12) ;yellow
SetColor(1,0,14) ;white
SetColor(2,8,6) ;blue
SetColor(4,0,0) ;black

RgbBlack(black)
RgbYellow(yellow)
RgbWhite(white)
RgbBlue(blue)

InitRgbImage(img,size,size,ptr)
FillRgbImage(img,black)

RgbCircle(img,size/2,size/2,size/2-1,white)
RgbCircle(img,2*size/5,2*size/5,size/5,white)
DrawImage(img,0,(96-size)/2)

FloodFill(img,3*size/5,3*size/5,white)
DrawImage(img,size,(96-size)/2)

FloodFill(img,2*size/5,2*size/5,blue)
DrawImage(img,2*size,(96-size)/2)

FloodFill(img,3*size/5,3*size/5,yellow)
DrawImage(img,3*size,(96-size)/2)

DO UNTIL CH#$FF OD
CH=$FF
RETURN</lang>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Flood_fill.png Screenshot from Atari 8-bit computer]


=={{header|Ada}}==
=={{header|Ada}}==