Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
106
Task/Bitmap-Flood-fill/Ada/bitmap-flood-fill-1.adb
Normal file
106
Task/Bitmap-Flood-fill/Ada/bitmap-flood-fill-1.adb
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
procedure Flood_Fill
|
||||
( Picture : in out Image;
|
||||
From : Point;
|
||||
Fill : Pixel;
|
||||
Replace : Pixel;
|
||||
Distance : Luminance := 20
|
||||
) is
|
||||
function Diff (A, B : Luminance) return Luminance is
|
||||
pragma Inline (Diff);
|
||||
begin
|
||||
if A > B then
|
||||
return A - B;
|
||||
else
|
||||
return B - A;
|
||||
end if;
|
||||
end Diff;
|
||||
|
||||
function "-" (A, B : Pixel) return Luminance is
|
||||
pragma Inline ("-");
|
||||
begin
|
||||
return Luminance'Max (Luminance'Max (Diff (A.R, B.R), Diff (A.G, B.G)), Diff (A.B, B.B));
|
||||
end "-";
|
||||
procedure Column (From : Point);
|
||||
procedure Row (From : Point);
|
||||
|
||||
Visited : array (Picture'Range (1), Picture'Range (2)) of Boolean :=
|
||||
(others => (others => False));
|
||||
|
||||
procedure Column (From : Point) is
|
||||
X1 : Positive := From.X;
|
||||
X2 : Positive := From.X;
|
||||
begin
|
||||
Visited (From.X, From.Y) := True;
|
||||
for X in reverse Picture'First (1)..From.X - 1 loop
|
||||
exit when Visited (X, From.Y);
|
||||
declare
|
||||
Color : Pixel renames Picture (X, From.Y);
|
||||
begin
|
||||
Visited (X, From.Y) := True;
|
||||
exit when Color - Replace > Distance;
|
||||
Color := Fill;
|
||||
X1 := X;
|
||||
end;
|
||||
end loop;
|
||||
for X in From.X + 1..Picture'Last (1) loop
|
||||
exit when Visited (X, From.Y);
|
||||
declare
|
||||
Color : Pixel renames Picture (X, From.Y);
|
||||
begin
|
||||
Visited (X, From.Y) := True;
|
||||
exit when Color - Replace > Distance;
|
||||
Color := Fill;
|
||||
X2 := X;
|
||||
end;
|
||||
end loop;
|
||||
for X in X1..From.X - 1 loop
|
||||
Row ((X, From.Y));
|
||||
end loop;
|
||||
for X in From.X + 1..X2 loop
|
||||
Row ((X, From.Y));
|
||||
end loop;
|
||||
end Column;
|
||||
|
||||
procedure Row (From : Point) is
|
||||
Y1 : Positive := From.Y;
|
||||
Y2 : Positive := From.Y;
|
||||
begin
|
||||
Visited (From.X, From.Y) := True;
|
||||
for Y in reverse Picture'First (2)..From.Y - 1 loop
|
||||
exit when Visited (From.X, Y);
|
||||
declare
|
||||
Color : Pixel renames Picture (From.X, Y);
|
||||
begin
|
||||
Visited (From.X, Y) := True;
|
||||
exit when Color - Replace > Distance;
|
||||
Color := Fill;
|
||||
Y1 := Y;
|
||||
end;
|
||||
end loop;
|
||||
for Y in From.Y + 1..Picture'Last (2) loop
|
||||
exit when Visited (From.X, Y);
|
||||
declare
|
||||
Color : Pixel renames Picture (From.X, Y);
|
||||
begin
|
||||
Visited (From.X, Y) := True;
|
||||
exit when Color - Replace > Distance;
|
||||
Color := Fill;
|
||||
Y2 := Y;
|
||||
end;
|
||||
end loop;
|
||||
for Y in Y1..From.Y - 1 loop
|
||||
Column ((From.X, Y));
|
||||
end loop;
|
||||
for Y in From.Y + 1..Y2 loop
|
||||
Column ((From.X, Y));
|
||||
end loop;
|
||||
end Row;
|
||||
|
||||
Color : Pixel renames Picture (From.X, From.Y);
|
||||
begin
|
||||
if Color - Replace <= Distance then
|
||||
Visited (From.X, From.Y) := True;
|
||||
Color := Fill;
|
||||
Column (From);
|
||||
end if;
|
||||
end Flood_Fill;
|
||||
19
Task/Bitmap-Flood-fill/Ada/bitmap-flood-fill-2.adb
Normal file
19
Task/Bitmap-Flood-fill/Ada/bitmap-flood-fill-2.adb
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
declare
|
||||
File : File_Type;
|
||||
begin
|
||||
Open (File, In_File, "Unfilledcirc.ppm");
|
||||
declare
|
||||
Picture : Image := Get_PPM (File);
|
||||
begin
|
||||
Close (File);
|
||||
Flood_Fill
|
||||
( Picture => Picture,
|
||||
From => (122, 30),
|
||||
Fill => (255,0,0),
|
||||
Replace => White
|
||||
);
|
||||
Create (File, Out_File, "Filledcirc.ppm");
|
||||
Put_PPM (File, Picture);
|
||||
Close (File);
|
||||
end;
|
||||
end;
|
||||
|
|
@ -1,55 +1,55 @@
|
|||
#NoEnv
|
||||
#SingleInstance, Force
|
||||
|
||||
SetBatchLines, -1
|
||||
CoordMode, Mouse
|
||||
CoordMode, Pixel
|
||||
SetBatchLines, -1
|
||||
CoordMode, Mouse
|
||||
CoordMode, Pixel
|
||||
return
|
||||
|
||||
CapsLock::
|
||||
KeyWait, CapsLock
|
||||
MouseGetPos, X, Y
|
||||
PixelGetColor, color, X, Y
|
||||
FloodFill(x, y, color, 0x000000, 1, "Esc")
|
||||
MsgBox Done!
|
||||
KeyWait, CapsLock
|
||||
MouseGetPos, X, Y
|
||||
PixelGetColor, color, X, Y
|
||||
FloodFill(x, y, color, 0x000000, 1, "Esc")
|
||||
MsgBox Done!
|
||||
Return
|
||||
|
||||
FloodFill( 0x, 0y, target, replacement, mode=1, key="" )
|
||||
{
|
||||
VarSetCapacity(Rect, 16, 0)
|
||||
hDC := DllCall("GetDC", UInt, 0)
|
||||
hBrush := DllCall("CreateSolidBrush", UInt, replacement)
|
||||
|
||||
l := 0
|
||||
while l >= 0
|
||||
{
|
||||
if getkeystate(key, "P")
|
||||
return
|
||||
x := %l%x, y := %l%y
|
||||
%l%p++
|
||||
p := %l%p
|
||||
PixelGetColor, color, x, y
|
||||
if (color = target)
|
||||
{
|
||||
NumPut(x, Rect, 0)
|
||||
NumPut(y, Rect, 4)
|
||||
NumPut(x+1, Rect, 8)
|
||||
NumPut(y+1, Rect, 12)
|
||||
DllCall("FillRect", UInt, hDC, Str, Rect, UInt, hBrush)
|
||||
}
|
||||
else if (p = 1)
|
||||
{
|
||||
%l%x := %l%y := %l%p := "", l--
|
||||
continue
|
||||
}
|
||||
if (p < 5)
|
||||
ol := l++
|
||||
, %l%x := %ol%x + (p = 1 ? 1 : p = 2 ? -1 : 0)
|
||||
, %l%y := %ol%y + (p = 3 ? 1 : p = 4 ? -1 : 0)
|
||||
else
|
||||
%l%x := %l%y := %l%p := "", l--
|
||||
}
|
||||
|
||||
DllCall("ReleaseDC", UInt, 0, UInt, hDC)
|
||||
DllCall("DeleteObject", UInt, hBrush)
|
||||
VarSetCapacity(Rect, 16, 0)
|
||||
hDC := DllCall("GetDC", UInt, 0)
|
||||
hBrush := DllCall("CreateSolidBrush", UInt, replacement)
|
||||
|
||||
l := 0
|
||||
while l >= 0
|
||||
{
|
||||
if getkeystate(key, "P")
|
||||
return
|
||||
x := %l%x, y := %l%y
|
||||
%l%p++
|
||||
p := %l%p
|
||||
PixelGetColor, color, x, y
|
||||
if (color = target)
|
||||
{
|
||||
NumPut(x, Rect, 0)
|
||||
NumPut(y, Rect, 4)
|
||||
NumPut(x+1, Rect, 8)
|
||||
NumPut(y+1, Rect, 12)
|
||||
DllCall("FillRect", UInt, hDC, Str, Rect, UInt, hBrush)
|
||||
}
|
||||
else if (p = 1)
|
||||
{
|
||||
%l%x := %l%y := %l%p := "", l--
|
||||
continue
|
||||
}
|
||||
if (p < 5)
|
||||
ol := l++
|
||||
, %l%x := %ol%x + (p = 1 ? 1 : p = 2 ? -1 : 0)
|
||||
, %l%y := %ol%y + (p = 3 ? 1 : p = 4 ? -1 : 0)
|
||||
else
|
||||
%l%x := %l%y := %l%p := "", l--
|
||||
}
|
||||
|
||||
DllCall("ReleaseDC", UInt, 0, UInt, hDC)
|
||||
DllCall("DeleteObject", UInt, hBrush)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,25 +16,25 @@ void FloodFillAlgorithm::flood(Point startPoint, Mat* tgtMat) {
|
|||
if (image->at<Vec3b>(startPoint) == srcColor) {
|
||||
|
||||
queue<Point> pointQueue;
|
||||
pointQueue.push(startPoint);
|
||||
pointQueue.push(startPoint);
|
||||
|
||||
while (!pointQueue.empty()) {
|
||||
Point p = pointQueue.front();
|
||||
pointQueue.pop();
|
||||
while (!pointQueue.empty()) {
|
||||
Point p = pointQueue.front();
|
||||
pointQueue.pop();
|
||||
|
||||
if (insideImage(p)) {
|
||||
if (insideImage(p)) {
|
||||
|
||||
if ((image->at<Vec3b>(p) == srcColor)) {
|
||||
image->at<Vec3b>(p) = tgtMat->at<Vec3b>(p);
|
||||
if ((image->at<Vec3b>(p) == srcColor)) {
|
||||
image->at<Vec3b>(p) = tgtMat->at<Vec3b>(p);
|
||||
|
||||
pointQueue.push(Point(p.x + 1, p.y));
|
||||
pointQueue.push(Point(p.x - 1, p.y));
|
||||
pointQueue.push(Point(p.x, p.y + 1));
|
||||
pointQueue.push(Point(p.x, p.y - 1));
|
||||
}
|
||||
}
|
||||
pointQueue.push(Point(p.x + 1, p.y));
|
||||
pointQueue.push(Point(p.x - 1, p.y));
|
||||
pointQueue.push(Point(p.x, p.y + 1));
|
||||
pointQueue.push(Point(p.x, p.y - 1));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,5 +5,5 @@ typedef struct {
|
|||
typedef rgb_color *rgb_color_p;
|
||||
|
||||
void floodfill(image img, int px, int py,
|
||||
rgb_color_p bankscolor,
|
||||
rgb_color_p rcolor);
|
||||
rgb_color_p bankscolor,
|
||||
rgb_color_p rcolor);
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ inline void _ffill_enqueue(_ffill_queue *q, int px, int py)
|
|||
inline double color_distance( rgb_color_p a, rgb_color_p b )
|
||||
{
|
||||
return sqrt( (double)(a->red - b->red)*(a->red - b->red) +
|
||||
(double)(a->green - b->green)*(a->green - b->green) +
|
||||
(double)(a->blue - b->blue)*(a->blue - b->blue) ) / (256.0*sqrt(3.0));
|
||||
(double)(a->green - b->green)*(a->green - b->green) +
|
||||
(double)(a->blue - b->blue)*(a->blue - b->blue) ) / (256.0*sqrt(3.0));
|
||||
}
|
||||
|
||||
inline void _ffill_rgbcolor(image img, rgb_color_p tc, int px, int py)
|
||||
|
|
@ -41,25 +41,25 @@ inline void _ffill_rgbcolor(image img, rgb_color_p tc, int px, int py)
|
|||
}
|
||||
|
||||
|
||||
#define NSOE(X,Y) do { \
|
||||
if ( ((X)>=0)&&((Y)>=0) && ((X)<img->width)&&((Y)<img->height)) { \
|
||||
_ffill_rgbcolor(img, &thisnode, (X), (Y)); \
|
||||
if ( color_distance(&thisnode, bankscolor) > tolerance ) { \
|
||||
if (color_distance(&thisnode, rcolor) > 0.0) { \
|
||||
put_pixel_unsafe(img, (X), (Y), rcolor->red, \
|
||||
rcolor->green, \
|
||||
rcolor->blue); \
|
||||
_ffill_enqueue(&head, (X), (Y)); \
|
||||
pixelcount++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
#define NSOE(X,Y) do { \
|
||||
if ( ((X)>=0)&&((Y)>=0) && ((X)<img->width)&&((Y)<img->height)) { \
|
||||
_ffill_rgbcolor(img, &thisnode, (X), (Y)); \
|
||||
if ( color_distance(&thisnode, bankscolor) > tolerance ) { \
|
||||
if (color_distance(&thisnode, rcolor) > 0.0) { \
|
||||
put_pixel_unsafe(img, (X), (Y), rcolor->red, \
|
||||
rcolor->green, \
|
||||
rcolor->blue); \
|
||||
_ffill_enqueue(&head, (X), (Y)); \
|
||||
pixelcount++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
unsigned int floodfill(image img, int px, int py,
|
||||
rgb_color_p bankscolor,
|
||||
rgb_color_p rcolor)
|
||||
rgb_color_p bankscolor,
|
||||
rgb_color_p rcolor)
|
||||
{
|
||||
_ffill_queue head;
|
||||
rgb_color thisnode;
|
||||
|
|
|
|||
37
Task/Bitmap-Flood-fill/Crystal/bitmap-flood-fill-1.cr
Normal file
37
Task/Bitmap-Flood-fill/Crystal/bitmap-flood-fill-1.cr
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
require "./pixmap"
|
||||
|
||||
class Pixmap
|
||||
def flood_fill (x, y, color)
|
||||
old_color = self[x, y]
|
||||
queue = Deque(Int32).new
|
||||
width = @width
|
||||
size = @data.size
|
||||
idx = y * width + x
|
||||
queue << idx
|
||||
|
||||
until queue.empty?
|
||||
idx = queue.shift
|
||||
next unless @data[idx] == old_color
|
||||
start = idx
|
||||
# go left
|
||||
limit = start // width * width
|
||||
while idx >= limit && @data[idx] == old_color
|
||||
@data[idx] = color
|
||||
up, dn = idx - width, idx + width
|
||||
queue << up if up >= 0 && @data[up] == old_color
|
||||
queue << dn if dn < size && @data[dn] == old_color
|
||||
idx -= 1
|
||||
end
|
||||
# go right
|
||||
limit = (start + width) // width * width
|
||||
idx = start + 1
|
||||
while idx < limit && @data[idx] == old_color
|
||||
@data[idx] = color
|
||||
up, dn = idx - width, idx + width
|
||||
queue << up if up >= 0 && @data[up] == old_color
|
||||
queue << dn if dn < size && @data[dn] == old_color
|
||||
idx += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
22
Task/Bitmap-Flood-fill/Crystal/bitmap-flood-fill-2.cr
Normal file
22
Task/Bitmap-Flood-fill/Crystal/bitmap-flood-fill-2.cr
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
require "./circle"
|
||||
require "./flood_fill"
|
||||
require "./write_ppm"
|
||||
require "./load_ppm"
|
||||
|
||||
img = Pixmap.new 120, 80, Color::WHITE
|
||||
img.circle 60, 40, 35, Color::BLACK
|
||||
img.circle 100, 20, 18, Color::RED
|
||||
|
||||
img.flood_fill 10, 10, Color.new(210, 230, 0)
|
||||
img.flood_fill 60, 40, Color.new(255, 128, 76)
|
||||
|
||||
img.write "crystal_flood_fill.ppm"
|
||||
|
||||
|
||||
img = Pixmap.load "Unfilledcirc.ppm"
|
||||
img.flood_fill 10, 10, Color.new(0, 128, 240)
|
||||
img.flood_fill img.width-1, img.height-1, Color.new(0, 128, 240)
|
||||
img.flood_fill 10, img.height//2, Color.new(240, 180, 10)
|
||||
img.flood_fill 100, 100, Color.new(255, 60, 10)
|
||||
|
||||
img.write "crystal_filledcirc.ppm"
|
||||
|
|
@ -15,23 +15,23 @@ FBSL.GETCLIENTRECT(ME, 0, 0, Breadth, Height)
|
|||
DrawCircles() ' Initialize circles
|
||||
|
||||
BEGIN EVENTS
|
||||
SELECT CASE CBMSG
|
||||
CASE WM_LBUTTONDOWN: FillCircles() ' Flood fill circles
|
||||
CASE WM_CLOSE: FBSL.RELEASEDC(ME, FBSL.GETDC) ' Clean up
|
||||
END SELECT
|
||||
SELECT CASE CBMSG
|
||||
CASE WM_LBUTTONDOWN: FillCircles() ' Flood fill circles
|
||||
CASE WM_CLOSE: FBSL.RELEASEDC(ME, FBSL.GETDC) ' Clean up
|
||||
END SELECT
|
||||
END EVENTS
|
||||
|
||||
SUB FillCircles()
|
||||
FILL(FBSL.GETDC, Breadth / 2, Height / 2, &HFFFF) ' Yellow: flood fill using intrinsics
|
||||
FOR DIM x = 0 TO Breadth / 2 ' Red: flood fill iteratively
|
||||
FOR DIM y = 0 TO Height / 2
|
||||
IF NOT POINT(FBSL.GETDC, x, y) THEN PSET(FBSL.GETDC, x, y, &HFF)
|
||||
NEXT
|
||||
NEXT
|
||||
FBSLSETTEXT(ME, "After Flood Fill") ' Reset form caption
|
||||
FILL(FBSL.GETDC, Breadth / 2, Height / 2, &HFFFF) ' Yellow: flood fill using intrinsics
|
||||
FOR DIM x = 0 TO Breadth / 2 ' Red: flood fill iteratively
|
||||
FOR DIM y = 0 TO Height / 2
|
||||
IF NOT POINT(FBSL.GETDC, x, y) THEN PSET(FBSL.GETDC, x, y, &HFF)
|
||||
NEXT
|
||||
NEXT
|
||||
FBSLSETTEXT(ME, "After Flood Fill") ' Reset form caption
|
||||
END SUB
|
||||
|
||||
SUB DrawCircles() ' Concatenate function calls
|
||||
CIRCLE(FBSL.GETDC, Breadth / 2, Height / 2, 85, &HFFFFFF, 0, 360, 1, TRUE) _ ' White
|
||||
(FBSL.GETDC, Breadth / 3, Height / 3, 30, 0, 0, 360, 1, TRUE) ' Black
|
||||
CIRCLE(FBSL.GETDC, Breadth / 2, Height / 2, 85, &HFFFFFF, 0, 360, 1, TRUE) _ ' White
|
||||
(FBSL.GETDC, Breadth / 3, Height / 3, 30, 0, 0, 360, 1, TRUE) ' Black
|
||||
END SUB
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
floodFill = function(bmp, x, y, targetColor, replacementColor)
|
||||
// Check if pixel is outside the bounds
|
||||
if not(0 < x < bmp.width) or not(0 < y < bmp.height) then return
|
||||
|
||||
// Check the current pixel color
|
||||
currentColor = bmp.pixel(x, y)
|
||||
if currentColor != targetColor then return
|
||||
|
||||
// Replace the color
|
||||
bmp.setPixel x, y, replacementColor
|
||||
// Recursively apply to adjacent pixels
|
||||
floodFill(bmp, x + 1, y, targetColor, replacementColor)
|
||||
floodFill(bmp, x - 1, y, targetColor, replacementColor)
|
||||
floodFill(bmp, x, y + 1, targetColor, replacementColor)
|
||||
floodFill(bmp, x, y - 1, targetColor, replacementColor)
|
||||
// Check if pixel is outside the bounds
|
||||
if not(0 < x < bmp.width) or not(0 < y < bmp.height) then return
|
||||
|
||||
// Check the current pixel color
|
||||
currentColor = bmp.pixel(x, y)
|
||||
if currentColor != targetColor then return
|
||||
|
||||
// Replace the color
|
||||
bmp.setPixel x, y, replacementColor
|
||||
// Recursively apply to adjacent pixels
|
||||
floodFill(bmp, x + 1, y, targetColor, replacementColor)
|
||||
floodFill(bmp, x - 1, y, targetColor, replacementColor)
|
||||
floodFill(bmp, x, y + 1, targetColor, replacementColor)
|
||||
floodFill(bmp, x, y - 1, targetColor, replacementColor)
|
||||
end function
|
||||
clear
|
||||
img = file.loadImage("Unfilledcirc.png")
|
||||
|
|
|
|||
|
|
@ -23,20 +23,20 @@ sub floodfill
|
|||
if ( colordistance(\@tcol, \@col) > $distparameter ) { return; }
|
||||
push @queue, [$x, $y];
|
||||
while ( @queue ) {
|
||||
my $pointref = shift(@queue);
|
||||
( $x, $y ) = @$pointref;
|
||||
if ( ($x < 0) || ($y < 0) || ( $x >= $img->width ) || ( $y >= $img->height ) ) { next; }
|
||||
if ( ! exists($visited{"$x,$y"}) ) {
|
||||
@col = $img->query_pixel($x, $y);
|
||||
if ( colordistance(\@tcol, \@col) <= $distparameter ) {
|
||||
$img->draw_point($x, $y);
|
||||
$visited{"$x,$y"} = 1;
|
||||
push @queue, [$x+1, $y];
|
||||
push @queue, [$x-1, $y];
|
||||
push @queue, [$x, $y+1];
|
||||
push @queue, [$x, $y-1];
|
||||
}
|
||||
}
|
||||
my $pointref = shift(@queue);
|
||||
( $x, $y ) = @$pointref;
|
||||
if ( ($x < 0) || ($y < 0) || ( $x >= $img->width ) || ( $y >= $img->height ) ) { next; }
|
||||
if ( ! exists($visited{"$x,$y"}) ) {
|
||||
@col = $img->query_pixel($x, $y);
|
||||
if ( colordistance(\@tcol, \@col) <= $distparameter ) {
|
||||
$img->draw_point($x, $y);
|
||||
$visited{"$x,$y"} = 1;
|
||||
push @queue, [$x+1, $y];
|
||||
push @queue, [$x-1, $y];
|
||||
push @queue, [$x, $y+1];
|
||||
push @queue, [$x, $y-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ class Bitmap {
|
|||
has Pixel @.data;
|
||||
|
||||
method pixel(
|
||||
$i where ^$!width,
|
||||
$j where ^$!height
|
||||
--> Pixel
|
||||
$i where ^$!width,
|
||||
$j where ^$!height
|
||||
--> Pixel
|
||||
) is rw { @!data[$i + $j * $!width] }
|
||||
}
|
||||
|
||||
role PPM {
|
||||
method P6 returns Blob {
|
||||
"P6\n{self.width} {self.height}\n255\n".encode('ascii')
|
||||
~ Blob.new: flat map { .R, .G, .B }, self.data
|
||||
"P6\n{self.width} {self.height}\n255\n".encode('ascii')
|
||||
~ Blob.new: flat map { .R, .G, .B }, self.data
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
64
Task/Bitmap-Flood-fill/Rebol/bitmap-flood-fill.rebol
Normal file
64
Task/Bitmap-Flood-fill/Rebol/bitmap-flood-fill.rebol
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
Rebol [
|
||||
title: "Rosetta code: Bitmap/Flood fill"
|
||||
file: %Bitmap-Flood_fill.r3
|
||||
url: https://rosettacode.org/wiki/Bitmap/Bitmap-Flood_fill
|
||||
]
|
||||
|
||||
flood-fill: function [
|
||||
image [image! file! url!]
|
||||
position [pair!] "Start position"
|
||||
color1 [tuple!] "Target color to replace"
|
||||
color2 [tuple!] "Replacement color"
|
||||
][
|
||||
unless image? image [image: load image] ;; Load image if not already loaded
|
||||
xsize: image/size/x
|
||||
ysize: image/size/y
|
||||
|
||||
color2/4: color1/4: 255 ;; Ensure both colors are fully opaque
|
||||
|
||||
que: copy []
|
||||
if image/:position != color1 [return image] ;; Bail if seed pixel isn't target color
|
||||
|
||||
append que position
|
||||
while [not empty? que][
|
||||
position: take que ;; Dequeue next position to process
|
||||
if image/:position == color1 [ ;; Skip if already recolored
|
||||
W: position
|
||||
;; Scan west, recoloring pixels until we leave the target-color region
|
||||
while [image/:W == color1][
|
||||
image/:W: color2
|
||||
next: W + 0x1 ;; Pixel south of W
|
||||
if all [next/y < ysize color1 == image/:next][append que next]
|
||||
next: W - 0x1 ;; Pixel north of W
|
||||
if all [next/y > 0 color1 == image/:next][append que next]
|
||||
next: W - 1x0 ;; Step west
|
||||
either next/x > 1 [W: next][break] ;; Stop at left edge
|
||||
]
|
||||
E: position + 1x0 ;; Start east scan one step right of seed
|
||||
if E/x < xsize [
|
||||
;; Scan east, recoloring pixels until we leave the target-color region
|
||||
while [image/:E == color1][
|
||||
image/:E: color2
|
||||
next: E + 0x1 ;; Pixel south of E
|
||||
if all [next/y < ysize color1 == image/:next][append que next]
|
||||
next: E - 0x1 ;; Pixel north of E
|
||||
if all [next/y > 0 color1 == image/:next][append que next]
|
||||
next: E + 1x0 ;; Step east
|
||||
either next/x < xsize [E: next][break] ;; Stop at right edge
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
image ;; Return the modified image
|
||||
]
|
||||
|
||||
;; Download the test image if not already cached locally
|
||||
unless exists? file: %Unfilledcirc.png [
|
||||
write file read https://static.wikitide.net/rosettacodewiki/0/0f/Unfilledcirc.png
|
||||
]
|
||||
|
||||
img: load %Unfilledcirc.png
|
||||
img: flood-fill img 200x200 white red
|
||||
img: flood-fill img 100x100 black blue
|
||||
|
||||
browse save %Filledcirc.png img ;; Save result and open in browser
|
||||
12
Task/Bitmap-Flood-fill/Uiua/bitmap-flood-fill.uiua
Normal file
12
Task/Bitmap-Flood-fill/Uiua/bitmap-flood-fill.uiua
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Drop a png onto this pane, then Run.
|
||||
&p$"Found a _" °img&frab "image.png"
|
||||
≡≡⊢ # Convert to greyscale.
|
||||
Sensitivity ← 0.3 # Lower is finer.
|
||||
N₄ ← [1_0 0_1 ¯ 1_0 0_¯1]
|
||||
[40_40]⊙0.8 # Starting point, fill colour.
|
||||
Good ← >Sensitivity⌵-⬚0.5⊡⊢ # Needs filling. Simple edges-check.
|
||||
# Take first of list. If needs fill, do so and then add
|
||||
# its four neighbours into queue. Repeat until queue is empty.
|
||||
⍢(⨬(↘1|◴⊂+N₄¤°⊂ ⊃(⋅∘|∘|⋅⋅⋅∘)◡(⍜(⊡|⋅∘)⊢))◡Good
|
||||
| >0⧻)
|
||||
⋅⊙⋅
|
||||
|
|
@ -4,11 +4,11 @@ fcn flood(pixmap, x,y, repl){ // slow!
|
|||
while(stack){
|
||||
x,y:=stack.pop();
|
||||
if((0<=y<h) and (0<=x<w)){
|
||||
p:=pixmap[x,y];
|
||||
if(p==targ){
|
||||
pixmap[x,y]=repl;
|
||||
stack.append( T(x-1,y), T(x+1,y), T(x, y-1), T(x, y+1) );
|
||||
}
|
||||
p:=pixmap[x,y];
|
||||
if(p==targ){
|
||||
pixmap[x,y]=repl;
|
||||
stack.append( T(x-1,y), T(x+1,y), T(x, y-1), T(x, y+1) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue