Grayscale image: Difference between revisions
m
→{{header|Wren}}: Changed to Wren S/H
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
m (→{{header|Wren}}: Changed to Wren S/H) |
||
(18 intermediate revisions by 6 users not shown) | |||
Line 1:
{{task|Image processing}}[[Category:Raster graphics operations]]
Many image processing algorithms are defined for [[wp:Grayscale|grayscale]] (or else monochromatic) images.
Line 242:
return Result;
end Color;</syntaxhighlight>
=={{header|ATS}}==
You will need <code>bitmap_task.sats</code> and <code>bitmap_task.dats</code> from [[Bitmap#ATS]].
===The ATS static file===
This file should be called <code>bitmap_grayscale_task.sats</code>.
<syntaxhighlight lang="ats">
#define ATS_PACKNAME "Rosetta_Code.bitmap_grayscale_task"
staload "bitmap_task.sats"
(*------------------------------------------------------------------*)
(* Here is a type for 8-bit grayscale pixels. It is analogous to the
rgb24 type defined in bitmap_task.sats. A gray8 is the size of a
uint8. (It is, in fact, a uint8, but here that fact is hidden, so
the ATS2 template and overload systems will know to treat gray8 as
a distinct type.) *)
abst@ype gray8 = uint8
fn {tk : tkind}
gray8_make_uint : g0uint tk -<> gray8
fn {tk : tkind}
gray8_make_int : g0int tk -<> gray8
fn {}
gray8_value : gray8 -<> uint8
overload gray8_make with gray8_make_uint
overload gray8_make with gray8_make_int
(*------------------------------------------------------------------*)
(* Pixel conversions. *)
fn {}
rgb24_to_gray8 : rgb24 -<> gray8 (* This is a lossy conversion. *)
fn {}
gray8_to_rgb24 : gray8 -<> rgb24
fn {}
rgb24_to_rgb24 : rgb24 -<> rgb24
fn {}
gray8_to_gray8 : gray8 -<> gray8
(*------------------------------------------------------------------*)
(* What follows is actually a general pixmap conversion mechanism,
not just one for conversions between gray8 and rgb24 pixels.
There are several ways to tell the function how to convert a
pixel. These methods include passing a function or any of the
different kinds of closure. However, instead I will do it with the
template system.
To wit: when calling pixmap_convert<a,b> one must have an
implementation of pixmap$pixel_convert<a,b> within the scope of the
call.
Note that pixmap_convert<a,a> can COPY a pixmap, although faster
implementations of copying may be possible. *)
fn {a, b : t@ype}
pixmap_convert_copy :
{w, h : int}
(!pixmap (a, w, h),
&array (b?, w * h) >> array (b, w * h)) ->
void
fn {a, b : t@ype}
pixmap_convert_alloc :
{w, h : int}
(!pixmap (a, w, h)) ->
[p : addr | null < p]
@(mfree_gc_v p | pixmap (b, w, h, p))
fn {a, b : t@ype}
pixmap$pixel_convert :
a -> b
overload pixmap_convert with pixmap_convert_copy
overload pixmap_convert with pixmap_convert_alloc
(*------------------------------------------------------------------*)
</syntaxhighlight>
===The ATS dynamic file===
This file should be called <code>bitmap_grayscale_task.dats</code>.
<syntaxhighlight lang="ats">
(*------------------------------------------------------------------*)
#define ATS_DYNLOADFLAG 0
#define ATS_PACKNAME "Rosetta_Code.bitmap_grayscale_task"
#include "share/atspre_staload.hats"
staload "bitmap_task.sats"
(* You need to staload bitmap_task.dats, so the ATS compiler will have
access to its implementations of templates. But we staload it
anonymously, so the programmer will not have access. *)
staload _ = "bitmap_task.dats"
staload "bitmap_grayscale_task.sats"
(*------------------------------------------------------------------*)
assume gray8 = uint8
implement {tk}
gray8_make_uint i =
let
(* Define some type conversions we are likely to want, but which
the prelude might not have implemented. (The ats2-xprelude
package will have these conversions, but I am avoiding
dependencies.) *)
extern castfn g0uint2uint_uint8_uint8 : uint8 -<> uint8
extern castfn g0uint2uint_uint_uint8 : uint -<> uint8
implement
g0uint2uint<uint8knd,uint8knd> i = g0uint2uint_uint8_uint8 i
implement
g0uint2uint<uintknd,uint8knd> i = g0uint2uint_uint_uint8 i
in
g0u2u i
end
implement {tk}
gray8_make_int i =
let
(* Define a type conversion we are likely to want, but which the
prelude might not have implemented. (The ats2-xprelude package
will have the conversion, but I am avoiding dependencies.) *)
extern castfn g0int2uint_int_uint8 : int -<> uint8
implement
g0int2uint<intknd,uint8knd> i = g0int2uint_int_uint8 i
in
g0i2u i
end
implement {}
gray8_value gray = gray
(*------------------------------------------------------------------*)
implement {}
rgb24_to_gray8 rgb =
(* There is no need for floating point here, although equivalent
integer calculations are a bit longer to write out. *)
let
extern castfn i2u32 : int -<> uint32
extern castfn u8_to_u32 : uint8 -<> uint32
extern castfn u32_to_u8 : uint32 -<> uint8
val @(r, g, b) = rgb24_values rgb
val r = u8_to_u32 r
and g = u8_to_u32 g
and b = u8_to_u32 b
val Y = (i2u32 2126 * r) + (i2u32 7152 * g) + (i2u32 722 * b)
val Y1 = Y / i2u32 10000
and Y0 = Y mod (i2u32 10000)
in
if Y0 < i2u32 5000 then
gray8_make (u32_to_u8 Y1)
else if i2u32 5000 < Y0 then
gray8_make (succ (u32_to_u8 Y1))
else if Y0 mod (i2u32 2) = i2u32 0 then
gray8_make (u32_to_u8 Y1)
else
gray8_make (succ (u32_to_u8 Y1))
end
implement {}
gray8_to_rgb24 gray =
rgb24_make @(gray, gray, gray)
implement {}
rgb24_to_rgb24 rgb = rgb
implement {}
gray8_to_gray8 gray = gray
(*------------------------------------------------------------------*)
implement {a, b}
pixmap_convert_copy {w, h} (pix_a, arr_b) =
let
val w : size_t w = width pix_a
and h : size_t h = height pix_a
prval () = lemma_g1uint_param w
prval () = lemma_g1uint_param h
in
if w = i2sz 0 then
let
prval () = mul_isfun (mul_make {w, h} (), mul_make {0, h} ())
prval () = view@ arr_b := array_v_unnil_nil{b?,b} (view@ arr_b)
in
end
else if h = i2sz 0 then
let
prval () = mul_isfun (mul_make {w, h} (), mul_make {w, 0} ())
prval () = view@ arr_b := array_v_unnil_nil{b?,b} (view@ arr_b)
in
end
else
let
stadef n = w * h
val n = w * h
prval () = mul_gte_gte_gte {w, h} ()
val p = addr@ arr_b
prval [p : addr] EQADDR () = eqaddr_make_ptr p
fun
loop {i : nat | i <= n}
.<i>.
(pf_b : !array_v (b?, p, i) >> array_v (b, p, i) |
pix_a : !pixmap (a, w, h),
i : size_t i)
: void =
if i = i2sz 0 then
let
prval () = pf_b := array_v_unnil_nil pf_b
in
end
else
let
val i1 = pred i
(* An exercise for a reader with nothing better to do:
write a proof that i1/w < h, so that the "mod h" can
be removed. It is there solely to provide a proof
that y < h. *)
val x = i1 mod w
and y = (i1 / w) mod h
prval @(pf_b1, pf_elt) = array_v_unextend pf_b
val elt = pixmap$pixel_convert<a,b> pix_a[x, y]
val () = ptr_set<b> (pf_elt | ptr_add<b> (p, i1), elt)
val () = loop (pf_b1 | pix_a, i1)
prval () = pf_b := array_v_extend (pf_b1, pf_elt)
in
end
in
loop (view@ arr_b | pix_a, n)
end
end
implement {a, b}
pixmap_convert_alloc {w, h} pix_a =
let
val w : size_t w = width pix_a
and h : size_t h = height pix_a
prval () = lemma_g1uint_param w
prval () = lemma_g1uint_param h
stadef n = w * h
val n = w * h
prval () = mul_gte_gte_gte {w, h} ()
val @(pf, pfgc | p) = array_ptr_alloc<b> n
val () = pixmap_convert<a,b> (pix_a, !p);
val pix_b = pixmap_make<b> (pf | w, h, p)
in
@(pfgc | pix_b)
end
(*------------------------------------------------------------------*)
(* Implementations of pixmap$pixel_convert for conversions between
gray8 and rgb24. The template system will inline these
implementations into the code. *)
implement
pixmap$pixel_convert<rgb24,gray8> rgb =
rgb24_to_gray8 rgb
implement
pixmap$pixel_convert<gray8,rgb24> gray =
gray8_to_rgb24 gray
implement
pixmap$pixel_convert<rgb24,rgb24> rgb =
rgb24_to_rgb24 rgb (* For using pixmap_convert to COPY a pixmap. *)
implement
pixmap$pixel_convert<gray8,gray8> gray =
gray8_to_gray8 gray (* For using pixmap_convert to COPY a pixmap. *)
(*------------------------------------------------------------------*)
(* Support for dump and load. The bytes will be written in a way
that is directly usable in PGM and PAM files. *)
typedef FILEstar = $extype"FILE *"
extern castfn FILEref2star : FILEref -<> FILEstar
implement
pixmap$pixels_dump<gray8> (outf, pixels, n) =
let
val num_written =
$extfcall (size_t, "fwrite", addr@ pixels, sizeof<gray8>, n,
FILEref2star outf)
in
num_written = n
end
implement
pixmap$pixels_load<gray8> (inpf, pixels, n, elt) =
let
prval [n : int] EQINT () = eqint_make_guint n
val num_read =
$extfcall (size_t, "fread", addr@ pixels, sizeof<gray8>, n,
FILEref2star inpf)
in
if num_read = n then
let
prval () = $UNSAFE.castvwtp2void{@[gray8][n]} pixels
in
true
end
else
begin
array_initize_elt<gray8> (pixels, n, elt);
false
end
end
(*------------------------------------------------------------------*)
#ifdef BITMAP_GRAYSCALE_TASK_TEST #then
implement
main0 () =
let
val failure_color = rgb24_make (255, 0, 0)
stadef w = 512
stadef h = 512
val w : size_t w = i2sz 512
and h : size_t h = i2sz 512
val @(pfgc1 | pix1) = pixmap_make<rgb24> (w, h)
val inpf = fileref_open_exn ("4.2.07.raw", file_mode_r)
val success = load<rgb24> (inpf, pix1, failure_color)
val () = fileref_close inpf
val- true = success
val @(pfgc2 | pix2) = pixmap_convert<rgb24,gray8> pix1
val @(pfgc3 | pix3) = pixmap_convert<gray8,rgb24> pix2
(* Write a Portable Pixel Map. *)
val outf = fileref_open_exn ("image-color.ppm", file_mode_w)
val () =
begin
fprintln! (outf, "P6");
fprintln! (outf, w, " ", h);
fprintln! (outf, "255");
ignoret (dump<rgb24> (outf, pix1))
end
val () = fileref_close outf
(* Write a Portable Gray Map. *)
val outf = fileref_open_exn ("image-gray.pgm", file_mode_w)
val () =
begin
fprintln! (outf, "P5");
fprintln! (outf, w, " ", h);
fprintln! (outf, "255");
ignoret (dump<gray8> (outf, pix2))
end
val () = fileref_close outf
(* Write a Portable Pixel Map. *)
val outf = fileref_open_exn ("image-gray.ppm", file_mode_w)
val () =
begin
fprintln! (outf, "P6");
fprintln! (outf, w, " ", h);
fprintln! (outf, "255");
ignoret (dump<rgb24> (outf, pix3))
end
val () = fileref_close outf
in
free (pfgc1 | pix1);
free (pfgc2 | pix2);
free (pfgc3 | pix3)
end
#endif
(*------------------------------------------------------------------*)
</syntaxhighlight>
There is a test program, which can be compiled and run as follows:
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_LIBC -DATS BITMAP_GRAYSCALE_TASK_TEST bitmap{,_grayscale}_task.{s,d}ats
$ ./a.out</pre>
It expects raw 24-bit color data in a file called <code>4.2.07.raw</code>. I have data from the SIPI test image "Peppers" in that file. Output will be three files, named <code>image-color.ppm</code>, <code>image-gray.pgm</code>, and <code>image-gray.ppm</code>. The first is "Peppers" as a PPM image, the second is the grayscale conversion as a PGM image, and the last is the grayscale conversion converted to a PPM image.
{{out}}
[[File:Bitmap grayscale task ATS color.jpg|thumb|none|alt=Bell peppers in different colors.]]
[[File:Bitmap grayscale task ATS gray.jpg|thumb|none|alt=Bell and other peppers in grayscale.]]
=={{header|BASIC256}}==
Line 917 ⟶ 1,327:
animage = gray
call output_ppm(an_unit, animage)</syntaxhighlight>
=={{header|FreeBASIC}}==
Line 955 ⟶ 1,357:
=={{header|FutureBasic}}==
There are several ways to handle grayscaling images in FB. Here's a function that accepts any of a variety of color images — JPEG, TIFF, PNG, BMP, GIF, etc. — and converts them to grayscale. The function uses a convenient build-in Core Image filter to generate the optimized grayscale image. This code compiles as a standalone application featuring a window with two image views, one showing the original color image, and the other with the converted grayscale image. The app uses a relatively square color image of flowers. It proportionately resizes the image to fit the left hand image view, and displays the converted image in the right hand view.
Resource: [[Media:Flowersfb.jpg]]
<syntaxhighlight lang="text">include resources "Flowersfb.jpg"
_window = 1
begin enum output 1
_imageviewColor
_imageviewGray
end enum
void local fn BuildWindow
CGRect r = fn CGRectMake( 0, 0, 580, 300 )
window _window, @"Color to Grayscale", r
r = fn CGRectMake( 20, 20, 260, 260 )
imageview _imageviewColor, YES, @"Flowersfb.jpg", r, NSImageScaleAxesIndependently, NSImageAlignCenter, NSImageFramePhoto
r = fn CGRectMake( 300, 20, 260, 260 )
imageview _imageviewGray, YES, @"Flowersfb.jpg", r, NSImageScaleAxesIndependently, NSImageAlignCenter, NSImageFramePhoto
end fn
local fn GrayscaleImage( image as ImageRef ) as ImageRef
CGSize size = fn ImageSize( image )
CFDataRef dta = fn ImageTIFFRepresentationUsingCompression( image, NSTIFFCompressionNone, 0.0 )
CIImageRef inputImage = fn CIImageWithData( dta )
ImageLockFocus( finalImage )
CIFilterRef filter = fn CIFilterWithNameAndInputParameters( @"CIPhotoEffectMono", @{kCIInputImageKey:inputImage} )
CIImageRef outputCIImage = fn CIFilterOutputImage( filter )
ImageUnlockFocus( finalImage )
end fn = finalImage
Line 996 ⟶ 1,398:
ImageRef grayflowers
colorFlowers = fn ImageNamed( @"
grayflowers = fn GrayscaleImage( colorFlowers )
ImageViewSetImage( _imageviewGray, grayFlowers )
HandleEvents</syntaxhighlight>
{{output}}
[[File:Color to Grayscale.png]]
=={{header|Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Grayscale_image}}
'''Solution'''
Note the use of the dot product in the calculation of the gray level.
[[File:Fōrmulæ - Grayscale image 01.png]]
'''Test case'''
[[File:Fōrmulæ - Grayscale image 02.png]]
[[File:Fōrmulæ - Grayscale image 03.png]]
=={{header|Go}}==
Line 1,357 ⟶ 1,772:
return bitmap
end</syntaxhighlight>
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module P6P5 {
Function Bitmap {
def x as long, y as long, Import as boolean, P5 as boolean
If match("NN") then {
Read x, y
} else.if Match("N") Then {
\\ is a file?
Read f as long
buffer whitespace as byte
if not Eof(f) then {
get #f, whitespace :P6$=eval$(whitespace)
get #f, whitespace : P6$+=eval$(whitespace)
def boolean getW=true, getH=true, getV=true
def long v
\\ str$("P6") has 2 bytes. "P6" has 4 bytes
P5=p6$=str$("P5")
If p6$=str$("P6") or P5 Then {
do {
get #f, whitespace
if Eval$(whitespace)=str$("#") then {
do {get #f, whitespace} until eval(whitespace)=10
} else {
select case eval(whitespace)
case 32, 9, 13, 10
{ if getW and x<>0 then {
getW=false
} else.if getH and y<>0 then {
getH=false
} else.if getV and v<>0 then {
getV=false
}
}
case 48 to 57
{if getW then {
x*=10
x+=eval(whitespace, 0)-48
} else.if getH then {
y*=10
y+=eval(whitespace, 0)-48
} else.if getV then {
v*=10
v+=eval(whitespace, 0)-48
}
}
End Select
}
iF eof(f) then Error "Not a ppm file"
} until getV=false
} else Error "Not a P6 ppm or P5 ppm file"
Import=True
}
} else Error "No proper arguments"
if x<1 or y<1 then Error "Wrong dimensions"
structure rgb {
red as byte
green as byte
blue as byte
}
m=len(rgb)*x mod 4
if m>0 then m=4-m ' add some bytes to raster line
m+=len(rgb) *x
Structure rasterline {
{
pad as byte*m
}
hline as rgb*x
}
Structure Raster {
magic as integer*4
w as integer*4
h as integer*4
{
linesB as byte*len(rasterline)*y
}
lines as rasterline*y
}
Buffer Clear Image1 as Raster
Return Image1, 0!magic:="cDIB", 0!w:=Hex$(x,2), 0!h:=Hex$(y, 2)
if not Import then Return Image1, 0!lines:=Str$(String$(chrcode$(255), Len(rasterline)*y))
Buffer Clear Pad as Byte*4
SetPixel=Lambda Image1, Pad,aLines=Len(Raster)-Len(Rasterline), blines=-Len(Rasterline) (x, y, c) ->{
where=alines+3*x+blines*y
if c>0 then c=color(c)
c-!
Return Pad, 0:=c as long
Return Image1, 0!where:=Eval(Pad, 2) as byte, 0!where+1:=Eval(Pad, 1) as byte, 0!where+2:=Eval(Pad, 0) as byte
}
GetPixel=Lambda Image1,aLines=Len(Raster)-Len(Rasterline), blines=-Len(Rasterline) (x,y) ->{
where=alines+3*x+blines*y
=color(Eval(image1, where+2 as byte), Eval(image1, where+1 as byte), Eval(image1, where as byte))
}
GetPixelGray=Lambda Image1,aLines=Len(Raster)-Len(Rasterline), blines=-Len(Rasterline) (x,y) ->{
where=alines+3*x+blines*y
grayval=round(0.2126*Eval(image1, where+2 as byte) + 0.7152*Eval(image1, where+1 as byte) + 0.0722*Eval(image1, where as byte), 0)
=color(grayval,grayval,grayval)
}
StrDib$=Lambda$ Image1, Raster -> {
=Eval$(Image1, 0, Len(Raster))
}
CopyImage=Lambda Image1 (image$) -> {
if left$(image$,12)=Eval$(Image1, 0, 24 ) Then {
Return Image1, 0:=Image$
} Else Error "Can't Copy Image"
}
Export2File=Lambda Image1, x, y (f) -> {
Print #f, "P6";chr$(10);"# Created using M2000 Interpreter";chr$(10);
Print #f, x;" ";y;" 255";chr$(10);
x2=x-1 : where=0 : rasterline=x*3
m=rasterline mod 4 : if m<>0 then rasterline+=4-m
Buffer pad as byte*3
For y1=y-1 to 0 {
where=rasterline*y1
For x1=0 to x2 {
Return pad, 0:=eval$(image1, 0!linesB!where, 3)
Push Eval(pad, 2) : Return pad, 2:=Eval(pad, 0), 0:=Number
Put #f, pad : where+=3
}
}
}
Export2FileGray=Lambda Image1, x, y (f) -> {
Print #f, "P5";chr$(10);"# Created using M2000 Interpreter";chr$(10);
Print #f, x;" ";y;" 255";chr$(10);
x2=x-1 : where=0 : rasterline=x*3
m=rasterline mod 4 : if m<>0 then rasterline+=4-m
Buffer pad as byte*3
Buffer bytepad as byte
const R=0.2126, G=0.7152, B=0.0722
For y1=y-1 to 0 {
where=rasterline*y1
For x1=0 to x2 {
Return pad, 0:=eval$(image1, 0!linesB!where, 3)
Return bytepad, 0:=round(R*Eval(pad, 2) + G*Eval(pad, 1) + B*Eval(pad, 0), 0)
Put #f, bytepad : where+=3
}
}
}
if Import then {
x0=x-1 : where=0
Buffer Pad1 as byte*3
Buffer Pad2 as byte
local rasterline=x*3
m=rasterline mod 4 : if m<>0 then rasterline+=4-m
For y1=y-1 to 0 {
where=rasterline*y1
For x1=0 to x0 {
if p5 then
Get #f, Pad2: m=eval(Pad2,0) : Return pad1, 0:=m, 1:=m, 2:=m
else
Get #f, Pad1 : Push Eval(pad1, 2) : Return pad1, 2:=Eval(pad1, 0), 0:=Number
End if
Return Image1, 0!linesB!where:=Eval$(Pad1) : where+=3
}
}
}
Group Bitmap {
SetPixel=SetPixel
GetPixel=GetPixel
Image$=StrDib$
Copy=CopyImage
ToFile=Export2File
ToFileGray=Export2FileGray
GetPixelGray=GetPixelGray
}
=Bitmap
}
Cls 5,0
A=Bitmap(15,10)
B=Bitmap(15,10)
c1=color(100, 200, 255)
c2=color(180, 250, 128)
For i=0 to 8
Call A.SetPixel(i, i, c1)
Call A.SetPixel(9, i,c2)
Next
Call A.SetPixel(i,i,c1)
// make a new one GrayScale (but 24bit) as B
For i=0 to 14 { For J=0 to 9 {Call B.SetPixel(i, j, A.GetPixelGray(i,j))}}
// place image A at 200 pixel from left margin, 100 pixel from top margin
Copy 200*twipsX, 100*twipsY use A.Image$(), 0, 400 ' zoom 400%, angle 0
// place image B at 400 pixel from left margin, 100 pixel from top margin
Copy 400*twipsX, 100*twipsY use B.Image$(), 0, 400 ' zoom 400%
Try {
Open "P6example.ppm" For Output as #f
Call A.Tofile(f)
Close #f
Open "P5example.ppm" For Output as #f
Call A.TofileGray(f)
Close #f
Open "P5example.ppm" For Input as #f
C=Bitmap(f)
close #f
Copy 600*twipsX, 100*twipsY use C.Image$(), 0, 400 ' zoom 400%
Open "P6example.ppm" For Input as #f
C=Bitmap(f)
close #f
// use of Top clause to make the border color transparent at rotation
Copy 800*twipsX, 100*twipsY top C.Image$(), 30, 400 ' zoom 400%, angle 30 degree
}
Print "Done"
}
P6P5
</syntaxhighlight>
[[File:Grayscale.png|thumb|alt=M2000 Console Output|M2000 Console Output]]
=={{header|Maple}}==
Line 1,387 ⟶ 2,009:
<syntaxhighlight lang="matlab">function [grayImage] = colortograyscale(inputImage)
grayImage = rgb2gray(inputImage);</syntaxhighlight>
=={{header|MiniScript}}==
This GUI implementation is for use with [http://miniscript.org/MiniMicro Mini Micro].
<syntaxhighlight lang="miniscript">
greyedColor = function(colr)
clist = color.toList(colr)
lum = [0.2126, 0.7152, 0.0722]
red = clist[0] * lum[0]
green = clist[1] * lum[1]
blue = clist[2] * lum[2]
grey = red + green + blue
return color.fromList([grey, grey, grey, clist[3]])
end function
toGreyScale = function(img)
greyImg = Image.create(img.width, img.height)
for x in range(0, img.width - 1)
for y in range(0, img.height - 1)
greyed = greyedColor(img.pixel(x, y))
greyImg.setPixel x, y, greyed
end for
end for
return greyImg
end function
clear
// The turtle and color wheel images are included with MiniMicro
turtle = file.loadImage("/sys/pics/animals/turtle.png")
greyTurtle = toGreyScale(turtle)
gfx.drawImage turtle, 0, 0
gfx.drawImage greyTurtle, turtle.width, 0
colorWheel = file.loadImage("/sys/pics/ColorWheel.png")
greyWheel = toGreyScale(colorWheel)
gfx.drawImage colorWheel, 0, 320
gfx.drawImage greyWheel, greyWheel.width, 320
</syntaxhighlight>
=={{header|Nim}}==
Line 2,201 ⟶ 2,862:
{{libheader|DOME}}
This script converts the image [https://rosettacode.org/File:Lenna100.jpg Lenna100.jpg] to grayscale and then displays the two images side by side.
<syntaxhighlight lang="
import "dome" for Window
|