Bitmap: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added solution for Action!)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(23 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{task|Raster graphics operations}}
{{task|Raster graphics operations}}
{{omit from|AWK}}
{{omit from|PARI/GP}}


Show a basic storage type to handle a simple RGB raster graphics image,
Show a basic storage type to handle a simple RGB raster graphics image,
Line 19: Line 17:
is available in the article [[write ppm file]].''
is available in the article [[write ppm file]].''
<br><br>
<br><br>

=={{header|11l}}==
=={{header|11l}}==
{{trans|Python}}
{{trans|Python}}


<lang 11l>T Colour
<syntaxhighlight lang="11l">T Colour
Byte r, g, b
Byte r, g, b


Line 74: Line 71:
bitmap.set(0, 1, black)
bitmap.set(0, 1, black)
assert(bitmap.get(0, 1) == black)
assert(bitmap.get(0, 1) == black)
bitmap.chardisplay()</lang>
bitmap.chardisplay()</syntaxhighlight>


{{out}}
{{out}}
Line 91: Line 88:
+--------------------+
+--------------------+
</pre>
</pre>

=={{header|Action!}}==
=={{header|Action!}}==
Part of the solution can be found in [http://www.rosettacode.org/wiki/Category:Action!_Bitmap_tools#RGBIMAGE.ACT RGBIMAGE.ACT]
{{libheader|Action! Bitmap tools}}
{{libheader|Action! Bitmap tools}}
<lang Action!>INCLUDE "H6:RGBIMAGE.ACT" ;from task Bitmap
<syntaxhighlight lang="action!">INCLUDE "H6:RGBIMAGE.ACT" ;from task Bitmap


RGB black,yellow,violet,blue
RGB black,yellow,violet,blue
Line 159: Line 156:
DO UNTIL CH#$FF OD
DO UNTIL CH#$FF OD
CH=$FF
CH=$FF
RETURN</lang>
RETURN</syntaxhighlight>
{{out}}
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Bitmap.png Screenshot from Atari 8-bit computer]
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Bitmap.png Screenshot from Atari 8-bit computer]

=={{header|ActionScript}}==
=={{header|ActionScript}}==
ActionScript 3 has a [http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html BitmapData class] (in the <code>flash.display</code> package) which can be used for storage and handling of bitmap images.
ActionScript 3 has a [http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html BitmapData class] (in the <code>flash.display</code> package) which can be used for storage and handling of bitmap images.
To display these images, the [http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Bitmap.html Bitmap] class can be used.
To display these images, the [http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Bitmap.html Bitmap] class can be used.


<syntaxhighlight lang="actionscript3">
<lang ActionScript3>
// To import the BitmapData class:
// To import the BitmapData class:
import flash.display.BitmapData;
import flash.display.BitmapData;
Line 190: Line 186:
// Fill the bitmap with a given colour (as 0xAARRGGBB) after construction
// Fill the bitmap with a given colour (as 0xAARRGGBB) after construction
bitmap.fillRect(bitmap.rect, 0xFF44FF44);
bitmap.fillRect(bitmap.rect, 0xFF44FF44);
</syntaxhighlight>
</lang>

=={{header|Ada}}==
=={{header|Ada}}==
The package interface:
The package interface:
<lang ada>package Bitmap_Store is
<syntaxhighlight lang="ada">package Bitmap_Store is
type Luminance is mod 2**8;
type Luminance is mod 2**8;
type Pixel is record
type Pixel is record
Line 210: Line 205:
X, Y : Positive;
X, Y : Positive;
end record;
end record;
end Bitmap_Store;</lang>
end Bitmap_Store;</syntaxhighlight>
The implementation of:
The implementation of:
<lang ada>with Ada.Text_IO; use Ada.Text_IO;
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;


package body Bitmap_Store is
package body Bitmap_Store is
Line 231: Line 226:
end Print;
end Print;


end Bitmap_Store;</lang>
end Bitmap_Store;</syntaxhighlight>
This can be used like:
This can be used like:
<lang ada>use Bitmap_Store; with Bitmap_Store;
<syntaxhighlight lang="ada">use Bitmap_Store; with Bitmap_Store;
...
...
X : Image (1..64, 1..64);
X : Image (1..64, 1..64);
Line 239: Line 234:
Fill (X, (255, 255, 255));
Fill (X, (255, 255, 255));
X (1, 2) := (R => 255, others => 0);
X (1, 2) := (R => 255, others => 0);
X (3, 4) := X (1, 2);</lang>
X (3, 4) := X (1, 2);</syntaxhighlight>

=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==
{{trans|ada}}
{{trans|ada}}
Line 250: Line 244:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.6 algol68g-2.6].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: prelude/Bitmap.a68'''<lang algol68># -*- coding: utf-8 -*- #
'''File: prelude/Bitmap.a68'''<syntaxhighlight lang="algol68"># -*- coding: utf-8 -*- #


MODE PIXEL = STRUCT(#SHORT# BITS red,green,blue);
MODE PIXEL = STRUCT(#SHORT# BITS red,green,blue);
Line 297: Line 291:
OP INIT = (REF IMAGE image)REF IMAGE: (init OF (CLASSOF image))(image);
OP INIT = (REF IMAGE image)REF IMAGE: (init OF (CLASSOF image))(image);


SKIP</lang>'''File: test/Bitmap.a68'''<lang algol68>#!/usr/bin/a68g --script #
SKIP</syntaxhighlight>'''File: test/Bitmap.a68'''<syntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
# -*- coding: utf-8 -*- #


Line 307: Line 301:
(fill OF class image) (x, white OF class image);
(fill OF class image) (x, white OF class image);
(print OF class image) (x)
(print OF class image) (x)
)</lang>
)</syntaxhighlight>
{{out}} (A 16x16 white block)
{{out}} (A 16x16 white block)
<pre>
<pre>
Line 327: Line 321:
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
</pre>
</pre>
=={{header|Applesoft BASIC}}==
The Bitmap Address (BA) of the image is 24576 in order to maximize available space for the image without clobbering hi-res graphics memory. Just enough room is allocated for a P6 header. The Bitmap Beginning (BB) is just after the header.


HIMEM is set to 8192 which is just below hi-res graphics memory. It isn't necessary to protect hi-res graphics memory, but it doesn't hurt. Larger images can be allocated by using a lower Bitmap Address.
<syntaxhighlight lang="gwbasic"> 100 W = 8
110 H = 8
120 BB = 24576 + LEN ( STR$ (W) + STR$ (H)) + 9: REM P6 HEADER
130 HIMEM: 8192
140 R = 255
150 G = 255
160 B = 0
170 C = R + G * 256 + B * 65536
180 GOSUB 600FILL
190 X = 4
200 Y = 5
210 R = 127
220 G = 127
230 B = 255
240 C = R + G * 256 + B * 65536
250 GOSUB 500"SET PIXEL"
260 X = 3
270 Y = 2
280 GOSUB 400"GET PIXEL"
290 PRINT "COLOR="C" RED="R" GREEN="G" BLUE="B;
300 END
400 A = BB + X * 3 + Y * W * 3
410 R = PEEK (A)
420 G = PEEK (A + 1)
430 B = PEEK (A + 2)
440 C = R + G * 256 + B * 65536
450 RETURN
500 R = C - INT (C / 256) * 256
510 B = INT (C / 65536)
520 G = INT (C / 256) - B * 256
530 A = BB + X * 3 + Y * W * 3
540 POKE A,R
550 POKE A + 1,G
560 POKE A + 2,B
570 RETURN
600 FOR Y = 0 TO H - 1
610 FOR X = 0 TO W - 1
620 GOSUB 500"SET PIXEL"
630 NEXT X,Y
640 RETURN</syntaxhighlight>
=={{header|ARM Assembly}}==
=={{header|ARM Assembly}}==
{{works with|Game Boy Advance}}
{{works with|Game Boy Advance}}
The Game Boy Advance's video memory is located at address 0x06000000, and is 240 pixels by 160 pixels, with 16 bits defining the color of each pixel. This is a linear array of memory; storing 0xFFFF at 0x06000000 for example will immediately make the top-left pixel of the screen turn white. The following routines are intended for the bitmap screen modes, and have only been tested in screen mode 3. There is no need to allocate this video memory as it is always available thanks to the hardware.
The Game Boy Advance's video memory is located at address 0x06000000, and is 240 pixels by 160 pixels, with 16 bits defining the color of each pixel. This is a linear array of memory; storing 0xFFFF at 0x06000000 for example will immediately make the top-left pixel of the screen turn white. The following routines are intended for the bitmap screen modes, and have only been tested in screen mode 3. There is no need to allocate this video memory as it is always available thanks to the hardware.


<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
Bitmap_FloodFill:
Bitmap_FloodFill:
;input:
;input:
Line 383: Line 420:
bl Bitmap_Locate
bl Bitmap_Locate
ldrH r3,[r2]
ldrH r3,[r2]
bx lr</lang>
bx lr</syntaxhighlight>
=={{header|ATS}}==

Because this code will be used in other tasks, I have separated it into "static" and "dynamic" source files. The former is the equivalent of an "interface" file in some other languages, and the latter is equivalent of an "implementation" file. I included some test code that gets compiled if you put the correct option on the compiler command line.

===The ATS static file===
This file should be called <code>bitmap_task.sats</code>.
<syntaxhighlight lang="ats">
#define ATS_PACKNAME "Rosetta_Code.bitmap_task"

(*------------------------------------------------------------------*)

(* I am going to do this at the most primitive level. So here is the
"abstractified" type, or really a whole set of different types:
w-by-h pixmap of values of type a, with pixel storage at address
p. The type is linear (‘use it once and only once’). We will make
pixmap a boxed type, so its size will be equal to that of a
pointer. (This is actually a general 2-dimensional array type!
But let us ignore that.) *)
absvtype pixmap (a : t@ype, w : int, h : int, p : addr) = ptr

(* A shorthand for a pixmap with its pixel storage at "some"
address. *)
vtypedef pixmap (a : t@ype, w : int, h : int) =
[p : addr] pixmap (a, w, h, p)

(* A shorthand for a pixmap with "some" width and height, and with its
pixel storage at "some" address. *)
vtypedef pixmap (a : t@ype) = [w, h : int] pixmap (a, w, h)

(* A shorthand for a pixmap with "some" POSITIVE width and POSITIVE
height, and with its pixel storage at "some" address. *)
vtypedef pixmap1 (a : t@ype) = [w, h : pos] pixmap (a, w, h)

(*------------------------------------------------------------------*)
(* Here are definitions for a small set of operations, including the
ones requested in the task document.

But note that, in ATS, we are careful about uninitialized data. It
is POSSIBLE to create an uninitialized pixmap, but NOT possible to
set or get individual pixels, if the pixmap is not already fully
initialized by some other means (such as "fill" or "load"). *)

fn {}
pixmap_width :
{a : t@ype}
{w, h : int}
(!pixmap (a, w, h)) -<> size_t w

fn {}
pixmap_height :
{a : t@ype}
{w, h : int}
(!pixmap (a, w, h)) -<> size_t h

fn {a : t@ype}
pixmap_make_array :
(* Make a new pixmap from an existing array. The array may be
anywhere (for instance, a stack frame or the heap), and need not
be initialized. *)
{w, h : int} {p : addr}
(array_v (a, p, w * h) | size_t w, size_t h, ptr p) ->
pixmap (a, w, h, p)

fn {a : t@ype}
pixmap_unmake :
(* Essentially the reverse of pixmap_make_array. Temporarily treat a
pixmap as an array. The array will be organized as rows from left
to right, with the rows themselves going from top to bottom. Thus
an index would be i = x + (y * w). *)
{w, h : int} {p : addr}
pixmap (a, w, h, p) ->
@(array_v (a, p, w * h) | size_t w, size_t h, ptr p)

prfn
pixmap_prove_index_bounds :
(* A proof that i = x + (y * w) is within bounds of the array
returned by pixmap_unmake. *)
{w, h : int}
{x, y : nat | x < w; y < h}
() -<prf>
[0 <= x + (y * w);
x + (y * w) < w * h]
void

fn {a : t@ype}
pixmap_make_uninitized :
(* Make a new uninitialized pixmap, with the pixels stored in the
heap. *)
{w, h : int}
(size_t w, size_t h) ->
[p : addr | null < p] @(mfree_gc_v p | pixmap (a?, w, h, p))

fn {a : t@ype}
pixmap_make_elt :
(* Make a new pixmap, initialized with a given element, with the
pixels stored in the heap. *)
{w, h : int}
(size_t w, size_t h, a) ->
[p : addr | null < p] @(mfree_gc_v p | pixmap (a, w, h, p))

fn {}
pixmap_free_storage_return :
(* Free a pixmap, returning the storage array to the user. *)
{a : t@ype}
{w, h : int} {p : addr}
pixmap (a, w, h, p) -> @(array_v (a, p, w * h) | ptr p)

fn {}
pixmap_free_storage_free :
(* If a pixmap's pixels were allocated in the heap, then free its
storage. *)
{a : t@ype}
{w, h : int} {p : addr}
(mfree_gc_v p | pixmap (a, w, h, p)) -> void

fn {a : t@ype}
pixmap_fill_elt :
(* Fill a pixmap with the given element. (Technically speaking, the
value of the first argument is consumed, and replaced by a new
value. Its type before and after is linear.) *)
{w, h : int} {p : addr}
(* The question mark means that the pixmap elements can start out
uninitialized. *)
(!pixmap (a?, w, h, p) >> pixmap (a, w, h, p), a) -> void

fn {a : t@ype}
{tk : tkind}
pixmap_set_at_guint :
(* Set a pixel at unsigned integer coordinates. You can do this only
on a pixmap that has been initialized. (It would be prohibitively
tedious to safely work with randomly located pixels, if the array
were not already fully initialized.) *)
{w, h : int}
{x, y : int | x < w; y < h}
(!pixmap (a, w, h), g1uint (tk, x), g1uint (tk, y), a) -> void

fn {a : t@ype}
{tk : tkind}
pixmap_set_at_gint :
(* Set a pixel, but with signed integer coordinates. *)
{w, h : int}
{x, y : nat | x < w; y < h}
(!pixmap (a, w, h), g1int (tk, x), g1int (tk, y), a) -> void

fn {a : t@ype} {tk : tkind}
pixmap_get_at_guint :
(* Get a pixel at unsigned integer coordinates. You can do this only
on a pixmap that has been initialized. *)
{w, h : int}
{x, y : int | x < w; y < h}
(!pixmap (a, w, h), g1uint (tk, x), g1uint (tk, y)) -> a

fn {a : t@ype} {tk : tkind}
pixmap_get_at_gint :
(* Get a pixel, but with signed integer coordinates. *)
{w, h : int}
{x, y : nat | x < w; y < h}
(!pixmap (a, w, h), g1int (tk, x), g1int (tk, y)) -> a

fn {a : t@ype}
pixmap_dump :
(* Dump the contents of a pixmap to an output stream, row by row as
in a PPM. You must implement the pixmap$pixels_dump template
function. (We are anticipating the task to write a PPM file, and
wish to do it in a nice way. I am likely to end up actually using
this code, after all.) *)
{w, h : int}
(* I return a success-or-failure value, to avoid committing to using
an exception here. There are circumstances in which exceptions are
not the best approach. *)
(FILEref, !pixmap (a, w, h)) -> bool (* success *)

fn {a : t@ype}
pixmap$pixels_dump :
(* A function that the writes n pixels to an output stream. (It
could be one pixel, it could be the entire image. From the user's
standpoint, it makes no difference. It is an implementation
detail HOW the function is called by pixmap_dump.) *)
{n : int}
(FILEref, &array (a, n), size_t n) -> bool (* success *)

fn {a : t@ype}
pixmap_load :
(* Load the contents of a pixmap from an input stream, row by row as
in a PPM. You must implement the pixmap$pixels_load template
function. A value of type a has to be given, to initialize the
array with if the loading fails. *)
{w, h : int} {p : addr}
(FILEref, !pixmap (a?, w, h, p) >> pixmap (a, w, h, p), a) ->
bool (* success *)

fn {a : t@ype}
pixmap$pixels_load :
(* A function that the reads n pixels from an input stream. (It
could be one pixel, it could be the entire image. From the user's
standpoint, it makes no difference. It is an implementation
detail HOW the function is called by pixmap_load.) *)
{n : int}
(FILEref, &array (a?, n) >> array (a, n), size_t n, a) ->
bool (* success *)

overload pixmap_make with pixmap_make_array
overload pixmap_make with pixmap_make_uninitized
overload pixmap_make with pixmap_make_elt

overload pixmap_free with pixmap_free_storage_return
overload pixmap_free with pixmap_free_storage_free
overload free with pixmap_free_storage_free

overload fill with pixmap_fill_elt

overload pixmap_set_at with pixmap_set_at_guint
overload pixmap_set_at with pixmap_set_at_gint
overload [] with pixmap_set_at

overload pixmap_get_at with pixmap_get_at_guint
overload pixmap_get_at with pixmap_get_at_gint
overload [] with pixmap_get_at

overload dump with pixmap_dump
overload load with pixmap_load

overload width with pixmap_width
overload height with pixmap_height

(*------------------------------------------------------------------*)
(* Here is a type for 24-bit RGB data. An RGB pixmap type thus can be
written as "pixmap (rgb24, w, h, p)".
There are, though you cannot see it here (they are in the dynamic
file), default implementations of pixmap$pixels_dump<rgb24> and
pixmap$pixels_load<rgb24>. These implementations are for dumping
raw data in PPM format. *)

(* It is an abstract type, the size of a triple of uint8. (It is, in
fact, a triple of uint8, but we hide this fact, so the template
system will not confuse the type with other triples of uint8. It is
a subtle matter. *)
abst@ype rgb24 = @(uint8, uint8, uint8)

fn {tk : tkind}
rgb24_make_uint_uint_uint :
(g0uint tk, g0uint tk, g0uint tk) -<> rgb24

fn {tk : tkind}
rgb24_make_int_int_int :
(g0int tk, g0int tk, g0int tk) -<> rgb24

fn {}
rgb24_make_tuple : @(uint8, uint8, uint8) -<> rgb24

fn {}
rgb24_values : rgb24 -<> @(uint8, uint8, uint8)

overload rgb24_make with rgb24_make_uint_uint_uint
overload rgb24_make with rgb24_make_int_int_int
overload rgb24_make with rgb24_make_tuple

(*------------------------------------------------------------------*)
</syntaxhighlight>

===The ATS dynamic file===
This file should be called <code>bitmap_task.dats</code>.
<syntaxhighlight lang="ats">
(*------------------------------------------------------------------*)

#define ATS_DYNLOADFLAG 0
#define ATS_PACKNAME "Rosetta_Code.bitmap_task"

#include "share/atspre_staload.hats"

staload "bitmap_task.sats"

(*------------------------------------------------------------------*)

(* The actual type, normally not seen by the user, is a boxed
record. *)
datavtype _pixmap (a : t@ype, w : int, h : int, p : addr) =
| _pixmap of
@{
pf = array_v (a, p, w * h) |
w = size_t w,
h = size_t h,
p = ptr p
}

(* Here is one of the ways to tie an abstract type to its
implementation: *)
assume pixmap (a, w, h, p) = _pixmap (a, w, h, p)
(* Another way is to use casts. *)

(*------------------------------------------------------------------*)

implement {}
pixmap_width pix =
case+ pix of _pixmap record => record.w

implement {}
pixmap_height pix =
case+ pix of _pixmap record => record.h

implement {a}
pixmap_make_array (pf | w, h, p) =
_pixmap @{pf = pf | w = w, h = h, p = p}

implement {a}
pixmap_unmake pix =
case+ pix of
| ~ _pixmap @{pf = pf | w = w, h = h, p = p} => @(pf | w, h, p)

primplement
pixmap_prove_index_bounds {w, h} {x, y} () =
let
prval () = mul_gte_gte_gte {y, w} ()
prval () = mul_gte_gte_gte {h - (y + 1), w} ()
in
end

implement {a}
pixmap_make_uninitized {w, h} (w, h) =
let
prval () = lemma_g1uint_param w (* Proves w >= 0. *)
prval () = lemma_g1uint_param h (* Proves h >= 0. *)
prval () = mul_gte_gte_gte {w, h} () (* Proves w*h >= 0. *)

val @(pf, pfgc | p) = array_ptr_alloc<a> (w * h)
val pix = pixmap_make<a?> (pf | w, h, p)
in
@(pfgc | pix)
end

implement {a}
pixmap_make_elt (w, h, elt) =
let
val @(pfgc | pix) = pixmap_make<a> (w, h)
in
fill<a> (pix, elt);
@(pfgc | pix)
end

implement {}
pixmap_free_storage_return pix =
case+ pix of
| ~ _pixmap record => @(record.pf | record.p)

implement {}
pixmap_free_storage_free (pfgc | pix) =
let
val @(pf | p) = pixmap_free pix
in
array_ptr_free (pf, pfgc | p)
end

implement {a}
pixmap_fill_elt {w, h} {p} (pix, elt) =
case+ pix of
| @ _pixmap record =>
let
prval () = lemma_g1uint_param (record.w)
prval () = lemma_g1uint_param (record.h)
prval () = mul_gte_gte_gte {w, h} ()
stadef n = w * h
val n : size_t n = record.w * record.h
and p : ptr p = record.p

fun
loop {i : nat | i <= n}
.<n - i>.
(pf_lft : array_v (a, p, i),
pf_rgt : array_v (a?, p + (i * sizeof a), n - i) |
i : size_t i)
: @(array_v (a, p, n) | ) =
if i = n then
let
prval () = array_v_unnil pf_rgt
in
@(pf_lft | )
end
else
let
prval @(pf_elt, pf_rgt) = array_v_uncons pf_rgt
val () = ptr_set<a> (pf_elt | ptr_add<a> (p, i), elt)
prval pf_lft = array_v_extend (pf_lft, pf_elt)
in
loop (pf_lft, pf_rgt | succ i)
end

val @(pf | ) = loop (array_v_nil (), record.pf | i2sz 0)
prval () = record.pf := pf
prval () = fold@ pix
in
end

implement {a} {tk}
pixmap_set_at_guint {w, h} {x, y} (pix, x, y, elt) =
case+ pix of
| @ _pixmap record =>
let
prval () = lemma_g1uint_param x
prval () = lemma_g1uint_param y

stadef n = w * h
stadef i = x + (y * w)

prval () = pixmap_prove_index_bounds {w, h} {x, y} ()
prval () = prop_verify {0 <= i && i < n} ()

(* I purposely store the data in an order such that you can
write something such as a PPM without looping separately
over x and y. Also, even if you did do an outer loop over y
and an inner loop over x, you would get the advantage of
data locality. *)
val i : size_t i = g1u2u x + (g1u2u y * record.w)
macdef pixels = !(record.p)
val () = pixels[i] := elt

prval () = fold@ pix
in
end

implement {a} {tk}
pixmap_set_at_gint (pix, x, y, elt) =
pixmap_set_at_guint<a><sizeknd> (pix, g1i2u x, g1i2u y, elt)

implement {a} {tk}
pixmap_get_at_guint {w, h} {x, y} (pix, x, y) =
case+ pix of
| @ _pixmap record =>
let
prval () = lemma_g1uint_param x
prval () = lemma_g1uint_param y

stadef n = w * h
stadef i = x + (y * w)

prval () = pixmap_prove_index_bounds {w, h} {x, y} ()
prval () = prop_verify {0 <= i && i < n} ()

val i : size_t i = g1u2u x + (g1u2u y * record.w)
macdef pixels = !(record.p)
val elt = pixels[i]

prval () = fold@ pix
in
elt
end

implement {a} {tk}
pixmap_get_at_gint (pix, x, y) =
pixmap_get_at_guint<a><sizeknd> (pix, g1i2u x, g1i2u y)

implement {a}
pixmap_dump (outf, pix) =
case+ pix of
| @ _pixmap record =>
let
macdef pixels = !(record.p)
val n = record.w * record.h
val success = pixmap$pixels_dump<a> (outf, pixels, n)
prval () = fold@ pix
in
success
end

implement {a}
pixmap_load (inpf, pix, elt) =
case+ pix of
| @ _pixmap record =>
let
macdef pixels = !(record.p)
val n = record.w * record.h
val success = pixmap$pixels_load<a> (inpf, pixels, n, elt)
prval () = fold@ pix
in
success
end

(*------------------------------------------------------------------*)

typedef FILEstar = $extype"FILE *"
extern castfn FILEref2star : FILEref -<> FILEstar

implement
pixmap$pixels_dump<rgb24> (outf, pixels, n) =
let
val num_written =
$extfcall (size_t, "fwrite", addr@ pixels, sizeof<rgb24>, n,
FILEref2star outf)
in
num_written = n
end

implement
pixmap$pixels_load<rgb24> (inpf, pixels, n, elt) =
let
prval [n : int] EQINT () = eqint_make_guint n
val num_read =
$extfcall (size_t, "fread", addr@ pixels, sizeof<rgb24>, n,
FILEref2star inpf)
in
if num_read = n then
let
prval () = $UNSAFE.castvwtp2void{@[rgb24][n]} pixels
in
true
end
else
begin
array_initize_elt<rgb24> (pixels, n, elt);
false
end
end

(*------------------------------------------------------------------*)

assume rgb24 = @(uint8, uint8, uint8)

implement {tk}
rgb24_make_uint_uint_uint (r, g, b) =
let
(* The prelude tends to miss implementations for type conversions
to uint8, so let us at least implement conversion from uint to
uint8. (I do not wish to use a general unsafe cast, because
that sort of code has caused me bugs before. C does not always
know how to do a type conversion correctly.) The ats2-xprelude
package has a much more complete set of implementations
(generated en masse by m4 macros), but for this task I am
avoiding such dependencies. *)
implement
g0uint2uint<uintknd,uint8knd> i =
let
extern castfn g0uint2uint_uint_uint8 : uint -<> uint8
in
g0uint2uint_uint_uint8 i
end
in
rgb24_make_tuple @(g0u2u r, g0u2u g, g0u2u b)
end

implement {tk}
rgb24_make_int_int_int (r, g, b) =
let
(* See the comment in rgb24_make_uint_uint_uint. *)
implement
g0int2uint<intknd,uint8knd> i =
let
extern castfn g0int2uint_int_uint8 : int -<> uint8
in
g0int2uint_int_uint8 i
end
in
rgb24_make @(g0i2u r, g0i2u g, g0i2u b)
end

implement {}
rgb24_make_tuple tup = tup

implement {}
rgb24_values rgb = rgb

(*------------------------------------------------------------------*)

#ifdef BITMAP_TASK_TEST #then

%{^
#include <limits.h>
%}

fn
test_sizeof_rgb24 () : void =
(* We want to be sure rgb24 takes up exactly 24 bits. Our dump and
load implementations depend on that. (If it prove not the case on
some platform, one can write, for that unanticipated platform,
special implementations of dump and load.) *)
let
val- true = sizeof<rgb24> = i2sz 3
val- true = sizeof<rgb24> * $extval (size_t, "CHAR_BIT") = i2sz 24
in
end

fn
test_pixel_load_copy_dump () : void =
(* Test loading, copying, and dumping of raw 24-bit RGB data from
SIPI image "Peppers", 4.2.07.tiff:
https://sipi.usc.edu/database/database.php?volume=misc&image=13#top
I have the data stored as "4.2.07.raw". *)
let
val failure_color = rgb24_make (0xFF, 0x00, 0x00)

val @(pfgc1 | pix1) = pixmap_make<rgb24> (i2sz 512, i2sz 512)
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_make<rgb24> (i2sz 512, i2sz 512,
failure_color)
fun
copy_pixels {x, y : nat | x <= 512; y <= 512}
.<512 - x, 512 - y>.
(pix1 : !pixmap (rgb24, 512, 512),
pix2 : !pixmap (rgb24, 512, 512),
x : int x,
y : int y) : void =
if x = 512 then
()
else if y = 512 then
copy_pixels (pix1, pix2, succ x, 0)
else
begin
pix2[x, y] := pix1[x, y];
copy_pixels (pix1, pix2, x, succ y)
end
val () = copy_pixels (pix1, pix2, 0, 0)

val outf = fileref_open_exn ("4.2.07.raw.dumped", file_mode_w)
val success = dump<rgb24> (outf, pix2)
val () = fileref_close outf
val- true = success

val status = $extfcall (int, "system",
"cmp 4.2.07.raw 4.2.07.raw.dumped")
val- true = status = 0
in
free (pfgc1 | pix1);
free (pfgc2 | pix2)
end

implement
main0 () =
begin
test_sizeof_rgb24 ();
test_pixel_load_copy_dump ()
end

#endif

(*------------------------------------------------------------------*)
</syntaxhighlight>

A test can be run if one has a 786432-byte file and names it <code>4.2.07.raw</code>. I used the raw data from a commonly used 512x512 test image. You can compile and run the test program thus:
<pre>$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_LIBC -DATS BITMAP_TASK_TEST bitmap_task.sats bitmap_task.dats
$ ./a.out</pre>
You should end up with a copy of the data in a file named <code>4.2.07.raw.dumped</code>.


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
{{works with|AutoHotkey_L}}
{{works with|AutoHotkey_L}}
<lang AutoHotkey>test:
<syntaxhighlight lang="autohotkey">test:
blue := color(0,0,255) ; rgb
blue := color(0,0,255) ; rgb
cyan := color(0,255,255)
cyan := color(0,255,255)
Line 479: Line 1,160:
{
{
return clr.R << 16 | clr.G << 8 | clr.B
return clr.R << 16 | clr.G << 8 | clr.B
}</lang>
}</syntaxhighlight>


=={{header|Axe}}==
=={{header|Axe}}==
Line 486: Line 1,167:
Two bitmaps can be masked together to create 3- and 4-color grayscale.
Two bitmaps can be masked together to create 3- and 4-color grayscale.


<lang axe>Buff(768)→Pic1
<syntaxhighlight lang="axe">Buff(768)→Pic1
Fill(Pic1,768,255)
Fill(Pic1,768,255)
Pxl-Off(45,30,Pic1)
Pxl-Off(45,30,Pic1)
Line 495: Line 1,176:
Pause 4500
Pause 4500


Disp pxl-Test(50,50,Pic1)▶Dec,i</lang>
Disp pxl-Test(50,50,Pic1)▶Dec,i</syntaxhighlight>


=={{header|BASIC256}}==
=={{header|BASIC}}==
==={{header|BASIC256}}===
[[Image:BASIC256_bitmap.png|right]]
[[Image:BASIC256_bitmap.png|right]]
<lang BASIC256>graphsize 30,30
<syntaxhighlight lang="basic256">graphsize 30,30
call fill(rgb(255,0,0))
call fill(rgb(255,0,0))
call setpixel(10,10,rgb(0,255,255))
call setpixel(10,10,rgb(0,255,255))
Line 516: Line 1,198:
color c
color c
plot x,y
plot x,y
end subroutine</lang>
end subroutine</syntaxhighlight>
{{out}}
{{out}}
<pre>pixel 10,10 is 4278255615
<pre>pixel 10,10 is 4278255615
pixel 20,20 is 4294901760</pre>
pixel 20,20 is 4294901760</pre>


=={{header|BBC BASIC}}==
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
{{works with|BBC BASIC for Windows}}
BBC BASIC expects a bitmap always to be associated with a window;
BBC BASIC expects a bitmap always to be associated with a window;
for simplicity this code uses the main output window.
for simplicity this code uses the main output window.
<lang bbcbasic> Width% = 200
<syntaxhighlight lang="bbcbasic"> Width% = 200
Height% = 200
Height% = 200
Line 558: Line 1,240:
col% = TINT(x%*2,y%*2)
col% = TINT(x%*2,y%*2)
SWAP ?^col%,?(^col%+2)
SWAP ?^col%,?(^col%+2)
= col%</lang>
= col%</syntaxhighlight>

=={{header|C}}==
=={{header|C}}==


Line 568: Line 1,249:
Start from [[Bitmap| bitmap page]]
Start from [[Bitmap| bitmap page]]


<lang c>#ifndef _IMGLIB_0
<syntaxhighlight lang="c">#ifndef _IMGLIB_0
#define _IMGLIB_0
#define _IMGLIB_0


Line 608: Line 1,289:
color_component b );
color_component b );
#define GET_PIXEL(IMG, X, Y) (IMG->buf[ ((Y) * IMG->width + (X)) ])
#define GET_PIXEL(IMG, X, Y) (IMG->buf[ ((Y) * IMG->width + (X)) ])
#endif</lang>
#endif</syntaxhighlight>


<lang c>image alloc_img(unsigned int width, unsigned int height)
<syntaxhighlight lang="c">image alloc_img(unsigned int width, unsigned int height)
{
{
image img;
image img;
Line 667: Line 1,348:
if (x < img->width && y < img->height)
if (x < img->width && y < img->height)
put_pixel_unsafe(img, x, y, r, g, b);
put_pixel_unsafe(img, x, y, r, g, b);
}</lang>
}</syntaxhighlight>

=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
This implementation uses a multidemensional array to store the Color structure
This implementation uses a multidemensional array to store the Color structure
Line 674: Line 1,354:
No exception catching for out-of-bounds errors if they occur,
No exception catching for out-of-bounds errors if they occur,
but provides Height and Width properties so a program using it can avoid them.
but provides Height and Width properties so a program using it can avoid them.
<lang csharp>public class Bitmap
<syntaxhighlight lang="csharp">public class Bitmap
{
{
public struct Color
public struct Color
Line 705: Line 1,385:
_imagemap[x, y] = color;
_imagemap[x, y] = color;
}
}
}</lang>
}</syntaxhighlight>

=={{header|C++}}==
=={{header|C++}}==


Line 712: Line 1,391:
{{libheader|boost}}
{{libheader|boost}}


<lang cpp>#include <iostream>
<syntaxhighlight lang="cpp">#include <iostream>
#include <boost/gil/gil_all.hpp>
#include <boost/gil/gil_all.hpp>
int main()
int main()
Line 731: Line 1,410:
rgb8_pixel_t px = const_view(img)(11, 20);
rgb8_pixel_t px = const_view(img)(11, 20);
std::cout << "the pixel at 11, 20 is " << (unsigned)px[0] << ':' << (unsigned)px[1] << ':' << (unsigned)px[2] << '\n';
std::cout << "the pixel at 11, 20 is " << (unsigned)px[0] << ':' << (unsigned)px[1] << ':' << (unsigned)px[2] << '\n';
}</lang>
}</syntaxhighlight>


See also [[Basic bitmap storage/C++]]
See also [[Basic bitmap storage/C++]]

=={{header|Clojure}}==
=={{header|Clojure}}==
<lang Clojure>(import '[java.awt Color Graphics Image]
<syntaxhighlight lang="clojure">(import '[java.awt Color Graphics Image]
'[java.awt.image BufferedImage])
'[java.awt.image BufferedImage])


Line 751: Line 1,429:


(defn get-pixel [image x y]
(defn get-pixel [image x y]
(Color. (.getRGB image x y)))</lang>
(Color. (.getRGB image x y)))</syntaxhighlight>

=={{header|Common Lisp}}==
=={{header|Common Lisp}}==


<lang lisp>(defpackage #:rgb-pixel-buffer
<syntaxhighlight lang="lisp">(defpackage #:rgb-pixel-buffer
(:use #:common-lisp)
(:use #:common-lisp)
(:export #:rgb-pixel-component #:rgb-pixel #:rgb-pixel-buffer
(:export #:rgb-pixel-component #:rgb-pixel #:rgb-pixel-buffer
Line 761: Line 1,438:
#:make-rgb-pixel #:make-rgb-pixel-buffer #:rgb-pixel-buffer-width
#:make-rgb-pixel #:make-rgb-pixel-buffer #:rgb-pixel-buffer-width
#:rgb-pixel-buffer-height #:rgb-pixel-red #:rgb-pixel-green
#:rgb-pixel-buffer-height #:rgb-pixel-red #:rgb-pixel-green
#:rgb-pixel-blue #:fill-rgb-pixel-buffer))</lang>
#:rgb-pixel-blue #:fill-rgb-pixel-buffer))</syntaxhighlight>


<lang lisp>(in-package #:rgb-pixel-buffer)
<syntaxhighlight lang="lisp">(in-package #:rgb-pixel-buffer)


(deftype rgb-pixel-component ()
(deftype rgb-pixel-component ()
Line 831: Line 1,508:
:for x :of-type fixnum :upfrom 0 :below width
:for x :of-type fixnum :upfrom 0 :below width
:do (setf (rgb-pixel buffer x y) pixel)))
:do (setf (rgb-pixel buffer x y) pixel)))
buffer))</lang>
buffer))</syntaxhighlight>


Example:
Example:


<lang lisp>(defvar *buffer* (make-rgb-pixel-buffer 10 10))
<syntaxhighlight lang="lisp">(defvar *buffer* (make-rgb-pixel-buffer 10 10))
(fill-rgb-pixel-buffer *buffer* +white+)
(fill-rgb-pixel-buffer *buffer* +white+)
(setf (rgb-pixel *buffer* 0 0) +red+)
(setf (rgb-pixel *buffer* 0 0) +red+)
(setf (rgb-pixel *buffer* 0 9) +red+)
(setf (rgb-pixel *buffer* 0 9) +red+)
(setf (rgb-pixel *buffer* 9 0) +red+)
(setf (rgb-pixel *buffer* 9 0) +red+)
(setf (rgb-pixel *buffer* 9 9) +red+)</lang>
(setf (rgb-pixel *buffer* 9 9) +red+)</syntaxhighlight>

=={{header|Crystal}}==
=={{header|Crystal}}==
<lang ruby>
<syntaxhighlight lang="ruby">
class RGBColor
class RGBColor
getter red, green, blue
getter red, green, blue
Line 880: Line 1,556:
bmap = Pixmap.new(5, 5)
bmap = Pixmap.new(5, 5)
pp bmap
pp bmap
</syntaxhighlight>
</lang>

=={{header|D}}==
=={{header|D}}==
This code is a little complex because many Tasks use this module for various purposes.
This code is a little complex because many Tasks use this module for various purposes.
<lang d>module bitmap;
<syntaxhighlight lang="d">module bitmap;


import std.stdio, std.array, std.exception, std.string, std.conv,
import std.stdio, std.array, std.exception, std.string, std.conv,
Line 1,063: Line 1,738:
img.textualShow;
img.textualShow;
}
}
}</lang>
}</syntaxhighlight>
Compiling it with <code>version=bitmap_main</code> prints:
Compiling it with <code>version=bitmap_main</code> prints:
{{out}}
{{out}}
Line 1,077: Line 1,752:
##############################</pre>
##############################</pre>
=={{header|Delphi}}==
=={{header|Delphi}}==
<syntaxhighlight lang="delphi">
<lang Delphi>
program BitmapTest;
program BitmapTest;


Line 1,191: Line 1,866:
end;
end;
bmp.Free;
bmp.Free;
end.</lang>
end.</syntaxhighlight>


=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
This is a pure Delphi example using standard Delphi controls and libraries that already have raster and bitmap objects and operations built in.

Bascially, Delphi has a powerful set of tools for manipulating graphic objects. All graphic objects including Screens, Printers, Windows or Bitmaps, have a property called a "Canvas." As a consequence, the same code can draw on the Screen, the Printer, a Window or a Bitmap. A Canvas has powerful function that allow you to draw pixels, lines, rectangles, circles, elispes, polygons and text on any graphic object. The code below demonstrates many of the function available in a canvas.
[[File:DelphiBitmaps.png|frame|none]]
<syntaxhighlight lang="Delphi">

procedure ShowBitmapFunctions(Image: TImage);
{Code to demonstrate some of the main features the Delphi "TCanvas" object}
var I,X,Y: integer;
var C: TColor;
begin
{Draw red rectangle with 3 pixels wide lines}
Image.Canvas.Pen.Color:=clRed;
Image.Canvas.Pen.Width:=3;
Image.Canvas.Rectangle(50,50,500,300);
{Flood fill rectangle blue}
Image.Canvas.Brush.Color:=clBlue;
Image.Canvas.FloodFill(55,55,clRed,fsBorder);
{Draw random dots on the screen}
for I:=1 to 1000 do
begin
X:=trunc((Random * 450) + 50);
Y:=trunc((Random * 250) + 50);
C:=RGB(Random(255),Random(255),Random(255));
{draw 9 pixels for each point to make dots more visible}
Image.Canvas.Pixels[X-1,Y-1]:=C;
Image.Canvas.Pixels[X ,Y-1]:=C;
Image.Canvas.Pixels[X+1,Y-1]:=C;
Image.Canvas.Pixels[X-1,Y ]:=C;
Image.Canvas.Pixels[X ,Y ]:=C;
Image.Canvas.Pixels[X+1,Y ]:=C;
Image.Canvas.Pixels[X-1,Y+1]:=C;
Image.Canvas.Pixels[X ,Y+1]:=C;
Image.Canvas.Pixels[X+1,Y+1]:=C;
end;
{Draw lime-green line from corner to cornder}
Image.Canvas.Pen.Color:=clLime;
Image.Canvas.MoveTo(50,50);
Image.Canvas.LineTo(500,300);
{Sample pixel color at 51,51}
C:=Image.Canvas.Pixels[51,51];
{Display the color value }
Image.Canvas.Brush.Color:=clAqua;
Image.Canvas.Font.Size:=25;
Image.Canvas.Font.Color:=clRed;
Image.Canvas.TextOut(5,5,IntToHex(C,8));
{Tell Delphi to update the Window}
Image.Repaint;
end;

</syntaxhighlight>
{{out}}
<pre>

Elapsed Time: 39.038 ms.

</pre>

=={{header|E}}==
=={{header|E}}==


Line 1,197: Line 1,935:
because it is most naturally written as a method on the image object.
because it is most naturally written as a method on the image object.


<lang e>def makeFlexList := <elib:tables.makeFlexList>
<syntaxhighlight lang="e">def makeFlexList := <elib:tables.makeFlexList>
def format := <import:java.lang.makeString>.format
def format := <import:java.lang.makeString>.format


Line 1,293: Line 2,031:
return flexImage
return flexImage
}</lang>
}</syntaxhighlight>


Examples/tests:
Examples/tests:


<lang e>? def i := makeImage(3, 3)
<syntaxhighlight lang="e">? def i := makeImage(3, 3)
# value: [000000 000000 000000 ]
# value: [000000 000000 000000 ]
# [000000 000000 000000 ]
# [000000 000000 000000 ]
Line 1,325: Line 2,063:
# value: 808080
# value: 808080


? i.writePPM(<import:java.io.makeFileOutputStream>(<file:~/Desktop/Rosetta.ppm>))</lang>
? i.writePPM(<import:java.io.makeFileOutputStream>(<file:~/Desktop/Rosetta.ppm>))</syntaxhighlight>

=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
<lang scheme>
<syntaxhighlight lang="scheme">
(lib 'plot)
(lib 'plot)
(define width 600)
(define width 600)
Line 1,361: Line 2,098:
(blue-at-xy 100 200)
(blue-at-xy 100 200)
→ 255
→ 255
</syntaxhighlight>
</lang>

=={{header|Elixir}}==
=={{header|Elixir}}==
Translation of the erlang version of the code.
Translation of the erlang version of the code.


<lang elixir>
<syntaxhighlight lang="elixir">
defmodule RosBitmap do
defmodule RosBitmap do
defrecord Bitmap, pixels: nil, shape: {0, 0}
defrecord Bitmap, pixels: nil, shape: {0, 0}
Line 1,395: Line 2,131:
end
end
end
end
</syntaxhighlight>
</lang>

=={{header|Erlang}}==
=={{header|Erlang}}==


Stores pixels as a 1d array and colors as binaries.
Stores pixels as a 1d array and colors as binaries.


<lang erlang>
<syntaxhighlight lang="erlang">
-module(ros_bitmap).
-module(ros_bitmap).


Line 1,427: Line 2,162:
<<R:8, G:8, B:8>> = array:get(Index, Pixels),
<<R:8, G:8, B:8>> = array:get(Index, Pixels),
{rgb, R, G, B}.
{rgb, R, G, B}.
</syntaxhighlight>
</lang>

=={{header|Euphoria}}==
=={{header|Euphoria}}==
<lang euphoria>-- Some color constants:
<syntaxhighlight lang="euphoria">-- Some color constants:
constant
constant
black = #000000,
black = #000000,
Line 1,452: Line 2,186:
-- Get pixel color
-- Get pixel color
atom color
atom color
color = image[400][300] -- Now color is #FF0000</lang>
color = image[400][300] -- Now color is #FF0000</syntaxhighlight>
?color -- Should print out 16711680
?color -- Should print out 16711680

=={{header|F Sharp|F#}}==
=={{header|F Sharp|F#}}==
FSharp can accomplish this task in several ways. This version is purely functional. The bitmap data structure does not mutate. Set pixel, for example, simply transforms the input bitmap into a new bitmap with that pixel set to the input color. If you have Framework 4.5, you can use ImmutableArray to force this immutability.
FSharp can accomplish this task in several ways. This version is purely functional. The bitmap data structure does not mutate. Set pixel, for example, simply transforms the input bitmap into a new bitmap with that pixel set to the input color. If you have Framework 4.5, you can use ImmutableArray to force this immutability.


'''Solution:'''
'''Solution:'''
<lang fsharp>
<syntaxhighlight lang="fsharp">
//pure functional version ... changing a pixel color provides a new Bitmap
//pure functional version ... changing a pixel color provides a new Bitmap
type Color = {red: byte; green: byte; blue: byte}
type Color = {red: byte; green: byte; blue: byte}
Line 1,484: Line 2,217:
| _ -> id)}
| _ -> id)}
let fill color bitmap = {bitmap with color = bitmap.color |> Array.map (fun _ ->color)}
let fill color bitmap = {bitmap with color = bitmap.color |> Array.map (fun _ ->color)}
</syntaxhighlight>
</lang>


'''Tests:'''
'''Tests:'''
<lang fsharp>
<syntaxhighlight lang="fsharp">
//setups
//setups
//==check pixel for color function
//==check pixel for color function
Line 1,519: Line 2,252:
let myBitmap6 = myBitmap5 |> setPixel {x=5u;y=10u} colorBlack
let myBitmap6 = myBitmap5 |> setPixel {x=5u;y=10u} colorBlack
printfn "Is 5,10 black: %b" (check myBitmap4 colorBlack (5u,10u))
printfn "Is 5,10 black: %b" (check myBitmap4 colorBlack (5u,10u))
</syntaxhighlight>
</lang>
{{out}}Is empty: true
{{out}}Is empty: true


Line 1,538: Line 2,271:
Is 5,10 black: true
Is 5,10 black: true
'''Usage:'''
'''Usage:'''
<lang fsharp>
<syntaxhighlight lang="fsharp">
bitmap 14u 14u
bitmap 14u 14u
|> fill {red = (byte) 200; green = (byte) 0; blue = (byte) 10}
|> fill {red = (byte) 200; green = (byte) 0; blue = (byte) 10}
Line 1,544: Line 2,277:
|> getPixel {x=5u;y=10u}
|> getPixel {x=5u;y=10u}
|> printfn "%A"
|> printfn "%A"
</syntaxhighlight>
</lang>
{{out}}
{{out}}
Some {red = 0uy;
Some {red = 0uy;
green = 0uy;
green = 0uy;
blue = 0uy;}
blue = 0uy;}

=={{header|Factor}}==
=={{header|Factor}}==
The image is a matrix of triples {R,G,B}.
The image is a matrix of triples {R,G,B}.
Line 1,555: Line 2,287:
most of them are not used right now, but we need them for drawing
most of them are not used right now, but we need them for drawing
so I put every thing here..
so I put every thing here..
<lang factor>USING: arrays fry kernel math.matrices sequences ;
<syntaxhighlight lang="factor">USING: arrays fry kernel math.matrices sequences ;
IN: rosettacode.raster.storage
IN: rosettacode.raster.storage


Line 1,580: Line 2,312:
: set-pixel ( {R,G,B} {i,j} image -- ) set-Mi,j ; inline
: set-pixel ( {R,G,B} {i,j} image -- ) set-Mi,j ; inline
: get-pixel ( {i,j} image -- pixel ) Mi,j ; inline
: get-pixel ( {i,j} image -- pixel ) Mi,j ; inline
</syntaxhighlight>
</lang>

=={{header|FBSL}}==
=={{header|FBSL}}==
Volatility in FBSL is a feature uncommon to most other languages. It is the ability of its intrinsic functions as well as its user-defined functions, DynAsm and DynC blocks, and functions imported from 3rd-party DLL's to preserve their return values between function calls in FBSL Variants that have the same names as their respective functions but use neither the parentheses nor the arguments.
Volatility in FBSL is a feature uncommon to most other languages. It is the ability of its intrinsic functions as well as its user-defined functions, DynAsm and DynC blocks, and functions imported from 3rd-party DLL's to preserve their return values between function calls in FBSL Variants that have the same names as their respective functions but use neither the parentheses nor the arguments.
Line 1,590: Line 2,321:


'''Using pure FBSL's built-in graphics functions:'''
'''Using pure FBSL's built-in graphics functions:'''
<lang qbasic>#DEFINE WM_LBUTTONDOWN 513
<syntaxhighlight lang="qbasic">#DEFINE WM_LBUTTONDOWN 513
#DEFINE WM_RBUTTONDOWN 516
#DEFINE WM_RBUTTONDOWN 516
#DEFINE WM_CLOSE 16
#DEFINE WM_CLOSE 16
Line 1,611: Line 2,342:
FBSL.RELEASEDC(ME, FBSL.GETDC)
FBSL.RELEASEDC(ME, FBSL.GETDC)
END SELECT
END SELECT
END EVENTS</lang>
END EVENTS</syntaxhighlight>
{{out}} [[File:FBSL_RC_Bitmap.PNG]]
{{out}} [[File:FBSL_RC_Bitmap.PNG]]

=={{header|Forth}}==
=={{header|Forth}}==
This creates bitmaps on the heap (they may be deallocated with "FREE").
This creates bitmaps on the heap (they may be deallocated with "FREE").
32-bit or greater cells are assumed, one pixel per cell.
32-bit or greater cells are assumed, one pixel per cell.
This automatically word-aligns rows, so a separate ''stride'' field is not required.
This automatically word-aligns rows, so a separate ''stride'' field is not required.
<lang forth>hex
<syntaxhighlight lang="forth">hex
0000ff constant red
0000ff constant red
00ff00 constant green
00ff00 constant green
Line 1,661: Line 2,391:
4 3 bitmap value test
4 3 bitmap value test
red test bfill
red test bfill
test bshow cr</lang>
test bshow cr</syntaxhighlight>

=={{header|Fortran}}==
=={{header|Fortran}}==
See [[Basic bitmap storage/Fortran]]
See [[Basic bitmap storage/Fortran]]


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>Screenres 320, 240, 8
<syntaxhighlight lang="freebasic">Screenres 320, 240, 8
Dim Shared As Integer w, h
Dim Shared As Integer w, h
Screeninfo w, h
Screeninfo w, h
Line 1,689: Line 2,416:


Bsave "FreeBASIC_bitmap.bmp", 0
Bsave "FreeBASIC_bitmap.bmp", 0
Sleep</lang>
Sleep</syntaxhighlight>


=={{header|Go}}==
=={{header|Go}}==
===Standard library===
===Standard library===
Line 1,699: Line 2,424:


Here's how to use the standard packages to do what this task requires:
Here's how to use the standard packages to do what this task requires:
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 1,755: Line 2,480:
fmt.Printf("Pixel at %7v has R=%d, G=%d, B=%d\n",
fmt.Printf("Pixel at %7v has R=%d, G=%d, B=%d\n",
image.Pt(30, 40), redc, greenc, bluec)
image.Pt(30, 40), redc, greenc, bluec)
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 1,767: Line 2,492:
===DIY===
===DIY===
Not a complete working program. Presented here are just types and functions requested by the task.
Not a complete working program. Presented here are just types and functions requested by the task.
<lang go>// Raster package used with a number of RC tasks.
<syntaxhighlight lang="go">// Raster package used with a number of RC tasks.
//
//
// For each task, documentation in package main source will list this
// For each task, documentation in package main source will list this
Line 1,886: Line 2,611:
}
}
return p.Rgb(), true
return p.Rgb(), true
}</lang>
}</syntaxhighlight>

=={{header|Haskell}}==
=={{header|Haskell}}==
We implement the <tt>Image</tt> type as an <tt>STArray</tt> so that we can use it in an imperative fashion in the <tt>ST</tt> monad.
We implement the <tt>Image</tt> type as an <tt>STArray</tt> so that we can use it in an imperative fashion in the <tt>ST</tt> monad.


<lang haskell>module Bitmap(module Bitmap) where
<syntaxhighlight lang="haskell">module Bitmap(module Bitmap) where
import Control.Monad
import Control.Monad
Line 1,967: Line 2,691:
mapImage :: (Color c, Color c') =>
mapImage :: (Color c, Color c') =>
(c -> c') -> Image s c -> ST s (Image s c')
(c -> c') -> Image s c -> ST s (Image s c')
mapImage f (Image i) = liftM Image $ mapArray f i</lang>
mapImage f (Image i) = liftM Image $ mapArray f i</syntaxhighlight>


This module provides an instance of <tt>Color</tt>.
This module provides an instance of <tt>Color</tt>.
<lang haskell>module Bitmap.RGB(module Bitmap.RGB) where
<syntaxhighlight lang="haskell">module Bitmap.RGB(module Bitmap.RGB) where


import Bitmap
import Bitmap
Line 1,992: Line 2,716:
toRGBImage :: Color c => Image s c -> ST s (Image s RGB)
toRGBImage :: Color c => Image s c -> ST s (Image s RGB)
toRGBImage = mapImage $ f . luminance
toRGBImage = mapImage $ f . luminance
where f x = RGB (x, x, x)</lang>
where f x = RGB (x, x, x)</syntaxhighlight>

=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==
The language has a built-in window data type with associated graphics primitives. A bitmap is just a window that isn't visible on-screen at the moment.
The language has a built-in window data type with associated graphics primitives. A bitmap is just a window that isn't visible on-screen at the moment.
<lang Icon>procedure makebitmap(width,height)
<syntaxhighlight lang="icon">procedure makebitmap(width,height)
return open("bitmap", "g", "canvas=hidden",
return open("bitmap", "g", "canvas=hidden",
"size="||width||","||height)
"size="||width||","||height)
Line 2,010: Line 2,733:
procedure getpixel(w,x,y)
procedure getpixel(w,x,y)
return Pixel(w,x,y)
return Pixel(w,x,y)
end</lang>
end</syntaxhighlight>

=={{header|J}}==
=={{header|J}}==
A number of addon packages are available for J that work with common image formats (including PPM), but here we will show a basic bitmap storage type as per the task description.
A number of addon packages are available for J that work with common image formats (including PPM), but here we will show a basic bitmap storage type as per the task description.
Line 2,023: Line 2,745:


'''Solution:'''
'''Solution:'''
<lang j>makeRGB=: 0&$: : (($,)~ ,&3)
<syntaxhighlight lang="j">makeRGB=: 0&$: : (($,)~ ,&3)
fillRGB=: makeRGB }:@$
fillRGB=: makeRGB }:@$
setPixels=: (1&{::@[)`(<"1@(0&{::@[))`]}
setPixels=: (1&{::@[)`(<"1@(0&{::@[))`]}
getPixels=: <"1@[ { ]</lang>
getPixels=: <"1@[ { ]</syntaxhighlight>


'''Examples:'''
'''Examples:'''


<lang j> myimg=: makeRGB 5 8 NB. create a bitmap with height 5 and width 8 (black)
<syntaxhighlight lang="j"> myimg=: makeRGB 5 8 NB. create a bitmap with height 5 and width 8 (black)
myimg=: 255 makeRGB 5 8 NB. create a white bitmap with height 5 and width 8
myimg=: 255 makeRGB 5 8 NB. create a white bitmap with height 5 and width 8
myimg=: 127 makeRGB 5 8 NB. create a gray bitmap with height 5 and width 8
myimg=: 127 makeRGB 5 8 NB. create a gray bitmap with height 5 and width 8
Line 2,045: Line 2,767:


}:$ myimg NB. get height and width of the image
}:$ myimg NB. get height and width of the image
5 8</lang>
5 8</syntaxhighlight>


<code>getPixels</code> and <code>setPixels</code> are generalized to set and get lists/arrays of pixels.
<code>getPixels</code> and <code>setPixels</code> are generalized to set and get lists/arrays of pixels.


<lang j>pixellist=: ,"0/~ i. 10 NB. row and column indices for 10 by 10 block of pixels
<syntaxhighlight lang="j">pixellist=: ,"0/~ i. 10 NB. row and column indices for 10 by 10 block of pixels


NB. create 10 by 10 block of magenta pixels in the middle of a 300 by 300 green image
NB. create 10 by 10 block of magenta pixels in the middle of a 300 by 300 green image
Line 2,055: Line 2,777:


NB. get pixel color for 10x10 block offset from magenta block
NB. get pixel color for 10x10 block offset from magenta block
subimg=: (140 + pixellist) getPixels myimg</lang>
subimg=: (140 + pixellist) getPixels myimg</syntaxhighlight>


To display the image in a window at any point for verification:
To display the image in a window at any point for verification:


<lang j>require 'viewmat'
<syntaxhighlight lang="j">require 'viewmat'
viewRGB=: [: viewrgb 256&#.
viewRGB=: [: viewrgb 256&#.


viewRGB myimg</lang>
viewRGB myimg</syntaxhighlight>


Note that height comes before width here. This is inconsistent with marketing of display resolutions, but matches J's treatment of dimensions.
Note that height comes before width here. This is inconsistent with marketing of display resolutions, but matches J's treatment of dimensions.

=={{header|Java}}==
=={{header|Java}}==
Solution {{libheader|AWT}}
Solution {{libheader|AWT}}
<lang java>import java.awt.Color;
<syntaxhighlight lang="java">import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Image;
Line 2,098: Line 2,819:
return image;
return image;
}
}
}</lang>
}</syntaxhighlight>


Test Program {{libheader|JUnit}}
Test Program {{libheader|JUnit}}
<lang java>import static org.junit.Assert.assertEquals;
<syntaxhighlight lang="java">import static org.junit.Assert.assertEquals;


import java.awt.Color;
import java.awt.Color;
Line 2,122: Line 2,843:
assertEquals(Color.CYAN, c2);
assertEquals(Color.CYAN, c2);
}
}
}</lang>
}</syntaxhighlight>

=={{header|JavaScript}}==
=={{header|JavaScript}}==


JavaScript can interact with a drawing context using the HTML5 Canvas API.
JavaScript can interact with a drawing context using the HTML5 Canvas API.


<lang javascript>
<syntaxhighlight lang="javascript">
// Set up the canvas
// Set up the canvas
var canvas = document.createElement("canvas"),
var canvas = document.createElement("canvas"),
Line 2,157: Line 2,877:
ctx.fillStyle = "black";
ctx.fillStyle = "black";
ctx.fillRect(width / 2, height / 2, 1, 1);
ctx.fillRect(width / 2, height / 2, 1, 1);
</syntaxhighlight>
</lang>

=={{header|Julia}}==
=={{header|Julia}}==
{{works with|Julia|0.6}}
{{works with|Julia|0.6}}


'''Using packages''' ([https://github.com/JuliaImages/Images.jl Images.jl], [https://github.com/JuliaGraphics/Colors.jl Colors.jl]):
'''Using packages''' ([https://github.com/JuliaImages/Images.jl Images.jl], [https://github.com/JuliaGraphics/Colors.jl Colors.jl]):
<lang julia>using Images, Colors
<syntaxhighlight lang="julia">using Images, Colors


Base.hex(p::RGB{T}) where T = join(hex(c(p), 2) for c in (red, green, blue))
Base.hex(p::RGB{T}) where T = join(hex(c(p), 2) for c in (red, green, blue))
Line 2,186: Line 2,905:
img[2, 3] = cfore
img[2, 3] = cfore
println("\nImage with a pixel set for foreground color:")
println("\nImage with a pixel set for foreground color:")
showhex(img)</lang>
showhex(img)</syntaxhighlight>


{{out}}
{{out}}
Line 2,215: Line 2,934:
FF00FF FF00FF FF00FF FF00FF FF00FF
FF00FF FF00FF FF00FF FF00FF FF00FF
FF00FF FF00FF FF00FF FF00FF FF00FF</pre>
FF00FF FF00FF FF00FF FF00FF FF00FF</pre>

=={{header|KonsolScript}}==
=={{header|KonsolScript}}==
<lang KonsolScript>function main() {
<syntaxhighlight lang="konsolscript">function main() {
Var:Number shape;
Var:Number shape;
Line 2,229: Line 2,947:
Screen:Render()
Screen:Render()
}
}
}</lang>
}</syntaxhighlight>

=={{header|Kotlin}}==
=={{header|Kotlin}}==
{{trans|Java}}
{{trans|Java}}
<lang scala>// version 1.1.4-3
<syntaxhighlight lang="scala">// version 1.1.4-3


import java.awt.Color
import java.awt.Color
Line 2,267: Line 2,984:
println(if (c2 == Color.cyan) "cyan" else "unknown")
println(if (c2 == Color.cyan) "cyan" else "unknown")
}
}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 2,274: Line 2,991:
The color of the pixel at (120, 120) is cyan
The color of the pixel at (120, 120) is cyan
</pre>
</pre>

=={{header|Lingo}}==
=={{header|Lingo}}==
<lang lingo>-- Creates a new image object of size 640x480 pixel and 32-bit color depth
<syntaxhighlight lang="lingo">-- Creates a new image object of size 640x480 pixel and 32-bit color depth
img = image(640, 480, 32)
img = image(640, 480, 32)


Line 2,286: Line 3,002:


-- Changes the color of the pixel at point (320, 240) to black
-- Changes the color of the pixel at point (320, 240) to black
img.setPixel(320, 240, rgb(0,0,0))</lang>
img.setPixel(320, 240, rgb(0,0,0))</syntaxhighlight>

=={{header|LiveCode}}==
=={{header|LiveCode}}==
LiveCode has built in support for importing and exporting PBM, JPEG, GIF, BMP or PNG graphics formats
LiveCode has built in support for importing and exporting PBM, JPEG, GIF, BMP or PNG graphics formats


<syntaxhighlight lang="livecode">
<lang LiveCode>
-- create an image container box at the center of the current stack window with default properties
-- create an image container box at the center of the current stack window with default properties
create image "test"
create image "test"
Line 2,312: Line 3,027:
-- the next line is copy of the Write a PPM task:
-- the next line is copy of the Write a PPM task:
export image "test" to file "~/Test.PPM" as paint -- paint format is one of PBM, PGM, or PPM
export image "test" to file "~/Test.PPM" as paint -- paint format is one of PBM, PGM, or PPM
</syntaxhighlight>
</lang>

=={{header|Lua}}==
=={{header|Lua}}==
===Original===
===Original===
<lang lua>function Allocate_Bitmap( width, height )
<syntaxhighlight lang="lua">function Allocate_Bitmap( width, height )
local bitmap = {}
local bitmap = {}
for i = 1, width do
for i = 1, width do
Line 2,337: Line 3,051:
function Get_Pixel( bitmap, x, y )
function Get_Pixel( bitmap, x, y )
return bitmap[x][y]
return bitmap[x][y]
end</lang>
end</syntaxhighlight>
This can be used like:
This can be used like:
<lang lua>bitmap = Allocate_Bitmap( 100, 50 )
<syntaxhighlight lang="lua">bitmap = Allocate_Bitmap( 100, 50 )
Fill_Bitmap( bitmap, { 15, 200, 80 } )
Fill_Bitmap( bitmap, { 15, 200, 80 } )
pixel = Get_Pixel( bitmap, 20, 25 )
pixel = Get_Pixel( bitmap, 20, 25 )
print( pixel[1], pixel[2], pixel[3] )</lang>
print( pixel[1], pixel[2], pixel[3] )</syntaxhighlight>
===Alternate===
===Alternate===
A more object-oriented and extensible approach for easier re-use elsewhere.
A more object-oriented and extensible approach for easier re-use elsewhere.
<lang lua>local Bitmap = {
<syntaxhighlight lang="lua">local Bitmap = {
new = function(self, width, height)
new = function(self, width, height)
local instance = setmetatable({ width=width, height=height }, self)
local instance = setmetatable({ width=width, height=height }, self)
Line 2,383: Line 3,097:
}
}
Bitmap.__index = Bitmap
Bitmap.__index = Bitmap
setmetatable(Bitmap, { __call = function (t, ...) return t:new(...) end })</lang>
setmetatable(Bitmap, { __call = function (t, ...) return t:new(...) end })</syntaxhighlight>
Usage:
Usage:
<lang lua>local bitmap = Bitmap(32,32)
<syntaxhighlight lang="lua">local bitmap = Bitmap(32,32)


-- default pixel representation is 32-bit packed ARGB on [0,255]
-- default pixel representation is 32-bit packed ARGB on [0,255]
Line 2,412: Line 3,126:
print(string.format("pixel at 0,0 = %s", bitmap:get(0,0)))
print(string.format("pixel at 0,0 = %s", bitmap:get(0,0)))
print(string.format("pixel at 1,1 = %s", bitmap:get(1,1)))
print(string.format("pixel at 1,1 = %s", bitmap:get(1,1)))
print(string.format("pixel at 2,2 = %s", bitmap:get(2,2)))</lang>
print(string.format("pixel at 2,2 = %s", bitmap:get(2,2)))</syntaxhighlight>
Caveat: Just be aware that ''as currently written'' the storage of complex types are referenced rather than copied. So, for example, using the clear() method with a table representing an RGB-tuple, will store the same identical reference throughout the bitmap - so direct modification of any one pixel's internal components would affect all other pixels as well. You should override the clear() method as appropriate to better support your desired pixel representation if this is not the behavior you desire.
Caveat: Just be aware that ''as currently written'' the storage of complex types are referenced rather than copied. So, for example, using the clear() method with a table representing an RGB-tuple, will store the same identical reference throughout the bitmap - so direct modification of any one pixel's internal components would affect all other pixels as well. You should override the clear() method as appropriate to better support your desired pixel representation if this is not the behavior you desire.
{{out}}
{{out}}
Line 2,424: Line 3,138:
pixel at 1,1 = green
pixel at 1,1 = green
pixel at 2,2 = blue</pre>
pixel at 2,2 = blue</pre>

=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
The easy way is to make a function to return an object with all functions on it, for specific image. We have to make the image in a way to render it to screen. The render statement get data in a string using a header of 12 characters (24 bytes). Raster lines are in down-top order. So last raster line is the top one. Also RGB is BGR in this data structure. Raster lines has to be aligned proper, so we may have add some bytes.
The easy way is to make a function to return an object with all functions on it, for specific image. We have to make the image in a way to render it to screen. The render statement get data in a string using a header of 12 characters (24 bytes). Raster lines are in down-top order. So last raster line is the top one. Also RGB is BGR in this data structure. Raster lines has to be aligned proper, so we may have add some bytes.
Line 2,433: Line 3,146:


===P3 ppm===
===P3 ppm===
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
\ Bitmap width in pixels, height in pixels
\ Bitmap width in pixels, height in pixels
\ Return a group object with some lambda as members: SetPixel, GetPixel, Image$
\ Return a group object with some lambda as members: SetPixel, GetPixel, Image$
Line 2,507: Line 3,220:
copy 500*twipsx,50*twipsy use A1.Image$()
copy 500*twipsx,50*twipsy use A1.Image$()


</syntaxhighlight>
</lang>


===P6 ppm===
===P6 ppm===
Need Version 9.4, Rev >=19
Need Version 9.4, Rev >=19
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module P6 {
Module P6 {
Function Bitmap {
Function Bitmap {
Line 2,671: Line 3,384:
}
}
P6
P6
</syntaxhighlight>
</lang>
Export using M2000 code for ppm is slower than using internal jpg and bmp encoders. Jpg encoder has a 100% quality, and because this image is black and white we get the best compression. Time 0.304sec is for three exports, two jpg and one bmp.
Export using M2000 code for ppm is slower than using internal jpg and bmp encoders. Jpg encoder has a 100% quality, and because this image is black and white we get the best compression. Time 0.304sec is for three exports, two jpg and one bmp.


Line 2,683: Line 3,396:
0.3040944sec
0.3040944sec
</pre>
</pre>

=={{header|Maple}}==
=={{header|Maple}}==
<lang Maple>allocateImg := proc(width, height)
<syntaxhighlight lang="maple">allocateImg := proc(width, height)
return Array(1..width, 1..height, 1..3);
return Array(1..width, 1..height, 1..3);
end proc:
end proc:
Line 2,707: Line 3,419:
end do:
end do:
return rgb:
return rgb:
end proc:</lang>
end proc:</syntaxhighlight>
{{Out|Use}}
{{Out|Use}}
<pre>a := allocateImg(200,200);
<pre>a := allocateImg(200,200);
Line 2,715: Line 3,427:
#Output the image
#Output the image
ImageTools:-Embed(ImageTools:-Create(a))</pre>
ImageTools:-Embed(ImageTools:-Create(a))</pre>

=={{header|Mathematica}} / {{header|Wolfram Language}}==
=={{header|Mathematica}} / {{header|Wolfram Language}}==
In Mathematica 7/8:
In Mathematica 7/8:
<lang Mathematica>img = Image[ConstantArray[{1, 0, 0}, {1000, 1000}]];
<syntaxhighlight lang="mathematica">img = Image[ConstantArray[{1, 0, 0}, {1000, 1000}]];
img = ReplacePart[img, {1, 1, 1} -> {0, 0, 1}];
img = ReplacePart[img, {1, 1, 1} -> {0, 0, 1}];
ImageValue[img, {1, 1}]</lang>
ImageValue[img, {1, 1}]</syntaxhighlight>
In Mathematica 9:
In Mathematica 9:
<lang Mathematica>img = Image[ConstantArray[{1, 0, 0}, {1000, 1000}]];
<syntaxhighlight lang="mathematica">img = Image[ConstantArray[{1, 0, 0}, {1000, 1000}]];
img = ReplacePixelValue[img, {1, 1} -> {0, 0, 1}];
img = ReplacePixelValue[img, {1, 1} -> {0, 0, 1}];
ImageValue[img, {1, 1}]</lang>
ImageValue[img, {1, 1}]</syntaxhighlight>

=={{header|MATLAB}}==
=={{header|MATLAB}}==
Save this in a file named Bitmap.mat in a folder named @Bitmap in your MATLAB root directory.
Save this in a file named Bitmap.mat in a folder named @Bitmap in your MATLAB root directory.
<syntaxhighlight lang="matlab">
<lang MATLAB>
%Bitmap class
%Bitmap class
%
%
Line 2,888: Line 3,598:
end %methods
end %methods
end %classdef
end %classdef
</syntaxhighlight>
</lang>


Sample Usage:
Sample Usage:
<syntaxhighlight lang="matlab">
<lang MATLAB>
>> img = Bitmap(20,30);
>> img = Bitmap(20,30);
>> img.fill([30 30 150]);
>> img.fill([30 30 150]);
Line 2,910: Line 3,620:
>> img.save()
>> img.save()
Save Complete
Save Complete
</syntaxhighlight>
</lang>

=={{header|MAXScript}}==
=={{header|MAXScript}}==


MAXScript provides a built-in Bitmap class.
MAXScript provides a built-in Bitmap class.
<lang maxscript>local myBitmap = bitmap 512 512</lang>
<syntaxhighlight lang="maxscript">local myBitmap = bitmap 512 512</syntaxhighlight>


Filling the image with a single colour can be accomplished at creation time by setting the color property.
Filling the image with a single colour can be accomplished at creation time by setting the color property.
<lang maxscript>local myBitmap = bitmap 512 512 color:(color 128 128 128)</lang>
<syntaxhighlight lang="maxscript">local myBitmap = bitmap 512 512 color:(color 128 128 128)</syntaxhighlight>


Use setPixels to set the colour of a pixel. This function takes an array of colours and is optimised to set the colours of a whole row of pixels.
Use setPixels to set the colour of a pixel. This function takes an array of colours and is optimised to set the colours of a whole row of pixels.
<lang maxscript>setPixels myBitmap [256, 256] #((color 255 255 255))</lang>
<syntaxhighlight lang="maxscript">setPixels myBitmap [256, 256] #((color 255 255 255))</syntaxhighlight>


Use getPixels to retrieve the colour of a pixel. As with setPixels, this function is optimised to retrieve one row at a time as an array of colour values.
Use getPixels to retrieve the colour of a pixel. As with setPixels, this function is optimised to retrieve one row at a time as an array of colour values.
<lang maxscript>local myPixel = getPixels myBitmap [256, 256] 1</lang>
<syntaxhighlight lang="maxscript">local myPixel = getPixels myBitmap [256, 256] 1</syntaxhighlight>

=={{header|MiniScript}}==
This GUI implementation is for use with [http://miniscript.org/MiniMicro Mini Micro].
<syntaxhighlight lang="miniscript">
// MiniMicro version of MiniScript has all the
// necessary methods built-in to complete this task.
width = 256
height = 256
colr = color.aqua

// Create the image with specified width/heigh. With
// no parameters, it defaults width/height to 64 and
// color to black
img = Image.create(width, height, colr)

// Create a diagonal line of multiple colors. Uses
// Cartesian coordinates so (0, 0) is lower left corner.
for i in range(0, 255)
img.setPixel i, i, color.rgb(i, i, i)
end for

// Get pixel color as RGBA hex values
print "Color at pixel (100, 100): " + img.pixel(100, 100)
print "Color at pixel (0, 0): " + img.pixel(0, 0)
print "Color at pixel (127, 127): " + img.pixel(127, 127)
print "Color at pixel (255, 255): " + img.pixel(255, 255)

// Display the image, resizing it to 127 x 127
gfx.drawImage img, 0, 0, 127, 127

// Save the file - accepted file extensions:
// tga, jpg, jpeg, and png (retains transparency)
// Optional third parameter is JPG compression quality.
file.saveImage "/usr/test.png", img
</syntaxhighlight>


=={{header|Modula-3}}==
=={{header|Modula-3}}==
Since this code is for use with other tasks, it uses an interface as well as the implementation module.
Since this code is for use with other tasks, it uses an interface as well as the implementation module.
<lang modula3>INTERFACE Bitmap;
<syntaxhighlight lang="modula3">INTERFACE Bitmap;


TYPE UByte = BITS 8 FOR [0 .. 16_FF];
TYPE UByte = BITS 8 FOR [0 .. 16_FF];
Line 2,951: Line 3,695:
PROCEDURE SetPixel(VAR pic: T; point: Point; color: Pixel);
PROCEDURE SetPixel(VAR pic: T; point: Point; color: Pixel);


END Bitmap.</lang>
END Bitmap.</syntaxhighlight>
<lang modula3>MODULE Bitmap;
<syntaxhighlight lang="modula3">MODULE Bitmap;


PROCEDURE NewImage(height, width: UByte): T RAISES {BadImage} =
PROCEDURE NewImage(height, width: UByte): T RAISES {BadImage} =
Line 2,999: Line 3,743:
BEGIN
BEGIN
END Bitmap.</lang>
END Bitmap.</syntaxhighlight>

=={{header|Nim}}==
=={{header|Nim}}==
<lang nim>type
<syntaxhighlight lang="nim">type
Luminance* = uint8
Luminance* = uint8
Index* = int
Index* = int
Line 3,065: Line 3,808:
img[1, 2] = color(255, 0, 0)
img[1, 2] = color(255, 0, 0)
img[3, 4] = img[1, 2]
img[3, 4] = img[1, 2]
img.print</lang>
img.print</syntaxhighlight>

=={{header|OCaml}}==
=={{header|OCaml}}==


<lang ocaml>let new_img ~width ~height =
<syntaxhighlight lang="ocaml">let new_img ~width ~height =
let all_channels =
let all_channels =
let kind = Bigarray.int8_unsigned
let kind = Bigarray.int8_unsigned
Line 3,083: Line 3,825:
r_channel,
r_channel,
g_channel,
g_channel,
b_channel)</lang>
b_channel)</syntaxhighlight>


and here is the type of the raster image this function returns:
and here is the type of the raster image this function returns:
Line 3,099: Line 3,841:
A more naive form would be this one:
A more naive form would be this one:


<lang ocaml>let new_img ~width ~height =
<syntaxhighlight lang="ocaml">let new_img ~width ~height =
let r_channel, g_channel, b_channel =
let r_channel, g_channel, b_channel =
let kind = Bigarray.int8_unsigned
let kind = Bigarray.int8_unsigned
Line 3,110: Line 3,852:
(r_channel,
(r_channel,
g_channel,
g_channel,
b_channel)</lang>
b_channel)</syntaxhighlight>


Here are the functions to fill with a color and to set one given pixel:
Here are the functions to fill with a color and to set one given pixel:


<lang ocaml>let fill_img ~img:(_, r_channel, g_channel, b_channel) ~color:(r,g,b) =
<syntaxhighlight lang="ocaml">let fill_img ~img:(_, r_channel, g_channel, b_channel) ~color:(r,g,b) =
Bigarray.Array2.fill r_channel r;
Bigarray.Array2.fill r_channel r;
Bigarray.Array2.fill g_channel g;
Bigarray.Array2.fill g_channel g;
Bigarray.Array2.fill b_channel b;
Bigarray.Array2.fill b_channel b;
;;</lang>
;;</syntaxhighlight>


<lang ocaml>let put_pixel_unsafe (_, r_channel, g_channel, b_channel) (r,g,b) =
<syntaxhighlight lang="ocaml">let put_pixel_unsafe (_, r_channel, g_channel, b_channel) (r,g,b) =
(fun x y ->
(fun x y ->
r_channel.{x,y} <- r;
r_channel.{x,y} <- r;
g_channel.{x,y} <- g;
g_channel.{x,y} <- g;
b_channel.{x,y} <- b;
b_channel.{x,y} <- b;
)</lang>
)</syntaxhighlight>


<lang ocaml>let get_pixel_unsafe (_, r_channel, g_channel, b_channel) =
<syntaxhighlight lang="ocaml">let get_pixel_unsafe (_, r_channel, g_channel, b_channel) =
(fun x y ->
(fun x y ->
(r_channel.{x,y},
(r_channel.{x,y},
g_channel.{x,y},
g_channel.{x,y},
b_channel.{x,y})
b_channel.{x,y})
)</lang>
)</syntaxhighlight>


we can overload these functions to make some bound checks:
we can overload these functions to make some bound checks:


<lang ocaml>let put_pixel img color x y =
<syntaxhighlight lang="ocaml">let put_pixel img color x y =
let _, r_channel,_,_ = img in
let _, r_channel,_,_ = img in
let width = Bigarray.Array2.dim1 r_channel
let width = Bigarray.Array2.dim1 r_channel
Line 3,159: Line 3,901:
if (y < 0) || (y >= height) then invalid_arg "y out of bounds";
if (y < 0) || (y >= height) then invalid_arg "y out of bounds";
get_pixel_unsafe img x y;
get_pixel_unsafe img x y;
;;</lang>
;;</syntaxhighlight>


and a function to get the dimensions:
and a function to get the dimensions:


<lang ocaml>let get_dims ~img:(_, r_channel, _, _) =
<syntaxhighlight lang="ocaml">let get_dims ~img:(_, r_channel, _, _) =
let width = Bigarray.Array2.dim1 r_channel
let width = Bigarray.Array2.dim1 r_channel
and height = Bigarray.Array2.dim2 r_channel in
and height = Bigarray.Array2.dim2 r_channel in
(width, height)</lang>
(width, height)</syntaxhighlight>

=={{header|Octave}}==
=={{header|Octave}}==
In Octave, images are matrix. A grayscale W×H image is stored as a W×H matrix, and RGB W×H image is stored as a W×H×3 image. Possible levels depend on the class of the storage: if it is double, the intensity is a floating point double number between 0 and 1; if it is uint8, the intensity is from 0 to 255; if it is uint16, the intensity is between 0 and 65535.
In Octave, images are matrix. A grayscale W×H image is stored as a W×H matrix, and RGB W×H image is stored as a W×H×3 image. Possible levels depend on the class of the storage: if it is double, the intensity is a floating point double number between 0 and 1; if it is uint8, the intensity is from 0 to 255; if it is uint16, the intensity is between 0 and 65535.


<lang octave>im = zeros(W, H, 3, "uint8"); % create an RGB image of width W and height H
<syntaxhighlight lang="octave">im = zeros(W, H, 3, "uint8"); % create an RGB image of width W and height H
% and intensity from 0 to 255; black (all zeros)
% and intensity from 0 to 255; black (all zeros)
im(:,:,1) = 255; % set R to 255
im(:,:,1) = 255; % set R to 255
Line 3,180: Line 3,921:
% at W/3, H/3
% at W/3, H/3
p = im(40,40,:); % or just store it in the vector p, so that
p = im(40,40,:); % or just store it in the vector p, so that
% p(1) is R, p(2) G and p(3) is B</lang>
% p(1) is R, p(2) G and p(3) is B</syntaxhighlight>


We can hide this in helper functions like:
We can hide this in helper functions like:


<lang octave>function im = create_rgb_image(w, h)
<syntaxhighlight lang="octave">function im = create_rgb_image(w, h)
im = zeros(w, h, 3, "uint8");
im = zeros(w, h, 3, "uint8");
endfunction
endfunction
Line 3,204: Line 3,945:
g = im(coord(1), coord(2), 2)
g = im(coord(1), coord(2), 2)
b = im(coord(1), coord(2), 3)
b = im(coord(1), coord(2), 3)
endfunction</lang>
endfunction</syntaxhighlight>


The only thing to note is that indexing start from 1.
The only thing to note is that indexing start from 1.


<lang octave>%example
<syntaxhighlight lang="octave">%example
im = create_rgb_image(200,200);
im = create_rgb_image(200,200);
for x = 1:128
for x = 1:128
Line 3,215: Line 3,956:


% it seems like saveimage wants double class on [0,1]
% it seems like saveimage wants double class on [0,1]
saveimage("image.ppm", double(im)./256, "ppm");</lang>
saveimage("image.ppm", double(im)./256, "ppm");</syntaxhighlight>

=={{header|OxygenBasic}}==
=={{header|OxygenBasic}}==
<lang oxygenbasic>
<syntaxhighlight lang="oxygenbasic">
'GENERIC BITMAP
'GENERIC BITMAP


Line 3,260: Line 4,000:


del m
del m
</syntaxhighlight>
</lang>

=={{header|Oz}}==
=={{header|Oz}}==
We first create a 2D array data type as a functor in a file "Array2D.oz":
We first create a 2D array data type as a functor in a file "Array2D.oz":
<lang oz>functor
<syntaxhighlight lang="oz">functor
export
export
New
New
Line 3,300: Line 4,039:


%% omitted: Clone, Map, Fold, ForAll
%% omitted: Clone, Map, Fold, ForAll
end</lang>
end</syntaxhighlight>


Based on this, we create a functor "Bitmap.oz":
Based on this, we create a functor "Bitmap.oz":
<lang oz>%% For real task prefer QTk's images:
<syntaxhighlight lang="oz">%% For real task prefer QTk's images:
%% http://www.mozart-oz.org/home/doc/mozart-stdlib/wp/qtk/html/node38.html
%% http://www.mozart-oz.org/home/doc/mozart-stdlib/wp/qtk/html/node38.html


Line 3,334: Line 4,073:


%% Omitted: MaxValue, ForAllPixels, Transform
%% Omitted: MaxValue, ForAllPixels, Transform
end</lang>
end</syntaxhighlight>


Some functions that are used in other tasks were omitted. See here for the complete module definitions: [[Basic bitmap storage/Oz]]
Some functions that are used in other tasks were omitted. See here for the complete module definitions: [[Basic bitmap storage/Oz]]

=={{header|Pascal}}==
=={{header|Pascal}}==
<lang Pascal>Interface
<syntaxhighlight lang="pascal">Interface
uses crt, { GetDir }
uses crt, { GetDir }
graph; { function GetPixel }
graph; { function GetPixel }
Line 3,470: Line 4,208:
end; { with bmpInfoHeader, bmpFileHeader }
end; { with bmpInfoHeader, bmpFileHeader }
end; { procedure }
end; { procedure }
</syntaxhighlight>
</lang>

=={{header|Perl}}==
=={{header|Perl}}==
{{libheader|Imlib2}}
{{libheader|Imlib2}}
<lang perl>#! /usr/bin/perl
<syntaxhighlight lang="perl">#! /usr/bin/perl


use strict;
use strict;
Line 3,500: Line 4,237:
my $img = Image::Imlib2->new_using_data(200, 200, $col x (200 * 200));
my $img = Image::Imlib2->new_using_data(200, 200, $col x (200 * 200));


exit 0;</lang>
exit 0;</syntaxhighlight>

=={{header|Phix}}==
=={{header|Phix}}==
Copy of [[Bitmap#Euphoria|Euphoria]]
Copy of [[Bitmap#Euphoria|Euphoria]]
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>-- Some colour constants:
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
constant black = #000000,
<span style="color: #000080;font-style:italic;">-- Some colour constants:</span>
-- blue = #0000FF,
<span style="color: #008080;">constant</span> <span style="color: #000000;">black</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#000000</span><span style="color: #0000FF;">,</span>
-- green = #00FF00,
-- red = #FF0000,
<span style="color: #000080;font-style:italic;">-- blue = #0000FF,
white = #FFFFFF
-- green = #00FF00,
-- red = #FF0000,</span>
<span style="color: #000000;">white</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">#FFFFFF</span>
-- Create new image filled with some colour
function new_image(integer width, integer height, integer fill_colour=black)
<span style="color: #000080;font-style:italic;">-- Create new image filled with some colour</span>
return repeat(repeat(fill_colour,height),width)
<span style="color: #008080;">function</span> <span style="color: #000000;">new_image</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">fill_colour</span><span style="color: #0000FF;">=</span><span style="color: #000000;">black</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fill_colour</span><span style="color: #0000FF;">,</span><span style="color: #000000;">height</span><span style="color: #0000FF;">),</span><span style="color: #000000;">width</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
-- Usage example:
sequence image = new_image(800,600)
<span style="color: #000080;font-style:italic;">-- Usage example:</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">image</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">new_image</span><span style="color: #0000FF;">(</span><span style="color: #000000;">800</span><span style="color: #0000FF;">,</span><span style="color: #000000;">600</span><span style="color: #0000FF;">)</span>
-- Set pixel color:
image[400][300] = white
<span style="color: #000080;font-style:italic;">-- Set pixel color:</span>

<span style="color: #000000;">image</span><span style="color: #0000FF;">[</span><span style="color: #000000;">400</span><span style="color: #0000FF;">][</span><span style="color: #000000;">300</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">white</span>
-- Get pixel color
integer colour = image[400][300] -- Now colour is #FF0000</lang>
<span style="color: #000080;font-style:italic;">-- Get pixel color</span>

<span style="color: #004080;">integer</span> <span style="color: #000000;">colour</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">image</span><span style="color: #0000FF;">[</span><span style="color: #000000;">400</span><span style="color: #0000FF;">][</span><span style="color: #000000;">300</span><span style="color: #0000FF;">]</span> <span style="color: #000080;font-style:italic;">-- Now colour is #FFFFFF</span>
<!--</syntaxhighlight>-->
=={{header|PHP}}==
=={{header|PHP}}==
<lang PHP>class Bitmap {
<syntaxhighlight lang="php">class Bitmap {
public $data;
public $data;
public $w;
public $w;
Line 3,564: Line 4,302:
$b->fill(2, 2, 18, 18, array(240,240,240));
$b->fill(2, 2, 18, 18, array(240,240,240));
$b->setPixel(0, 15, array(255,0,0));
$b->setPixel(0, 15, array(255,0,0));
print_r($b->getPixel(3,3)); //(240,240,240)</lang>
print_r($b->getPixel(3,3)); //(240,240,240)</syntaxhighlight>

=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
For time critical applications this would be done with inline-C in PicoLisp,
For time critical applications this would be done with inline-C in PicoLisp,
but especially for small bitmaps the following makes sense.
but especially for small bitmaps the following makes sense.
<lang PicoLisp># Create an empty image of 120 x 90 pixels
<syntaxhighlight lang="picolisp"># Create an empty image of 120 x 90 pixels
(setq *Ppm (make (do 90 (link (need 120)))))
(setq *Ppm (make (do 90 (link (need 120)))))


Line 3,585: Line 4,322:
# Get the color of a pixel
# Get the color of a pixel
(de ppmGetPixel (Ppm X Y)
(de ppmGetPixel (Ppm X Y)
(get Ppm Y X) )</lang>
(get Ppm Y X) )</syntaxhighlight>

=={{header|PL/I}}==
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
/* Declaration for an image, suitable for BMP files. */
/* Declaration for an image, suitable for BMP files. */
declare image(0:500, 0:500) bit (24) aligned;
declare image(0:500, 0:500) bit (24) aligned;
Line 3,615: Line 4,351:


declare image(*,*) controlled bit (24) aligned;
declare image(*,*) controlled bit (24) aligned;
</syntaxhighlight>
</lang>

=={{header|Processing}}==
=={{header|Processing}}==
<lang java>PGraphics bitmap = createGraphics(100,100); // Create the bitmap
<syntaxhighlight lang="java">PGraphics bitmap = createGraphics(100,100); // Create the bitmap
bitmap.beginDraw();
bitmap.beginDraw();
bitmap.background(255, 0, 0); // Fill bitmap with red rgb color
bitmap.background(255, 0, 0); // Fill bitmap with red rgb color
Line 3,627: Line 4,362:
color c = get(50, 50); // Get the color of same pixel
color c = get(50, 50); // Get the color of same pixel
if(b == c) print("Color changed correctly"); // Verify
if(b == c) print("Color changed correctly"); // Verify
</syntaxhighlight>
</lang>


=={{header|Prolog}}==
=={{header|Prolog}}==
<lang prolog>
<syntaxhighlight lang="prolog">
:- module(bitmap, [
:- module(bitmap, [
new_bitmap/3,
new_bitmap/3,
Line 3,683: Line 4,416:
replace0(X,Row,RGB,New_Row),
replace0(X,Row,RGB,New_Row),
replace0(Y,Pixels,New_Row,New_Pixels).
replace0(Y,Pixels,New_Row,New_Pixels).
</syntaxhighlight>
</lang>

=={{header|PureBasic}}==
=={{header|PureBasic}}==
<lang PureBasic>w=800 : h=600
<syntaxhighlight lang="purebasic">w=800 : h=600
CreateImage(1,w,h)
CreateImage(1,w,h)
;1 is internal id of image
;1 is internal id of image
Line 3,698: Line 4,430:
; check if we set it right (should be 255)
; check if we set it right (should be 255)
Debug Blue(Point(10,10))
Debug Blue(Point(10,10))
</syntaxhighlight>
</lang>

=={{header|Python}}==
=={{header|Python}}==
See [[Basic bitmap storage/Python]]
See [[Basic bitmap storage/Python]]

=={{header|QBasic}}==
{{works with|QBasic|1.1}}
<syntaxhighlight lang="qbasic">SUB establecePixel (x AS INTEGER, y AS INTEGER, c AS INTEGER)
PSET (x, y), cyan
END SUB

SUB rellenar (c AS INTEGER)
SHARED w, h
LINE (0, 0)-(w / 3, h / 3), red, BF
END SUB

SCREEN 13
w = 320: h = 200
CONST cyan = 3, red = 4

rellenar (12)
CALL establecePixel(10, 10, cyan)
LOCATE 12
PRINT "pixel 10,10 is "; POINT(10, 10)
PRINT "pixel 20,20 is "; POINT(20, 10)</syntaxhighlight>


=={{header|R}}==
=={{header|R}}==
Line 3,708: Line 4,460:
R can write to most bitmap image formats by default (mostly for the purpose of saving graphs), however there is no built-in way of manipulating images. The pixmap package reads, writes and manipulates portable bitmap file types: PBM, PGM, PPM.
R can write to most bitmap image formats by default (mostly for the purpose of saving graphs), however there is no built-in way of manipulating images. The pixmap package reads, writes and manipulates portable bitmap file types: PBM, PGM, PPM.
See also, the image function, and the rimage and ReadImage packages, which use libjpeg to read JPEG and PNG files.
See also, the image function, and the rimage and ReadImage packages, which use libjpeg to read JPEG and PNG files.
<lang r># See the class definitions and constructors with, e.g.
<syntaxhighlight lang="r"># See the class definitions and constructors with, e.g.
getClass("pixmapIndexed", package=pixmap)
getClass("pixmapIndexed", package=pixmap)
pixmapIndexed
pixmapIndexed
Line 3,726: Line 4,478:
pmcol[i,j]
pmcol[i,j]
}
}
getcol(p2, 3, 4) #red</lang>
getcol(p2, 3, 4) #red</syntaxhighlight>

=={{header|Racket}}==
=={{header|Racket}}==
<lang racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket


Line 3,771: Line 4,522:
;; to view the final image:
;; to view the final image:
bm
bm
</syntaxhighlight>
</lang>

=={{header|Raku}}==
=={{header|Raku}}==
(formerly Perl 6)
(formerly Perl 6)
<lang perl6>class Pixel { has UInt ($.R, $.G, $.B) }
<syntaxhighlight lang="raku" line>class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
class Bitmap {
has UInt ($.width, $.height);
has UInt ($.width, $.height);
Line 3,803: Line 4,553:
$b.set-pixel( 7, 5, Pixel.new( R => 100, G => 200, B => 0) );
$b.set-pixel( 7, 5, Pixel.new( R => 100, G => 200, B => 0) );


say $b.perl;</lang>
say $b.perl;</syntaxhighlight>


Thanks to the <tt>rw</tt> trait on the <tt>pixel</tt> method, we don't actually need to define two separate methods, <tt>set-pixel</tt> and <tt>get-pixel</tt>, but that is an explicit requirement of the task. (Beware your presuppositions! In Raku, accessors only determine identity, not use. In particular, identity is considered orthogonal to lvalue/rvalue context.)
Thanks to the <tt>rw</tt> trait on the <tt>pixel</tt> method, we don't actually need to define two separate methods, <tt>set-pixel</tt> and <tt>get-pixel</tt>, but that is an explicit requirement of the task. (Beware your presuppositions! In Raku, accessors only determine identity, not use. In particular, identity is considered orthogonal to lvalue/rvalue context.)

=={{header|RapidQ}}==
=={{header|RapidQ}}==


Line 3,813: Line 4,562:
The commands to draw on the canvas are in the procedure PaintCanvas, which is executed each time the canvas need to be (re)painted.
The commands to draw on the canvas are in the procedure PaintCanvas, which is executed each time the canvas need to be (re)painted.


<lang rapidq>DECLARE SUB PaintCanvas
<syntaxhighlight lang="rapidq">DECLARE SUB PaintCanvas


CREATE form AS QForm
CREATE form AS QForm
Line 3,836: Line 4,585:
END SUB
END SUB


form.ShowModal</lang>
form.ShowModal</syntaxhighlight>

=={{header|REXX}}==
=={{header|REXX}}==
===version 1===
===version 1===
Line 3,845: Line 4,593:


The image (raster) created was also written to a file &nbsp; ('''image.PPM''') &nbsp; to show verification of the image.
The image (raster) created was also written to a file &nbsp; ('''image.PPM''') &nbsp; to show verification of the image.
<lang rexx>/*REXX program demonstrates how to process/display a simple RGB raster graphics image.*/
<syntaxhighlight lang="rexx">/*REXX program demonstrates how to process/display */
red = 'ff 00 00'x /*a method to define a red value. */
/* a simple RGB raster graphics image.*/
blue = '00 00 ff'x /*" " " " " blue " */
red = 'ff 00 00'x /*a method to define a red value. */
@. = /*define entire @. array to nulls. */
blue = '00 00 ff'x /*' ' ' ' ' blue ' */
outFN = 'image' /*the filename of the output image PPM */
pixel='' /*define entire pixel. array to nulls.*/
sWidth = 500; sHeight= 500 /*the screen width and height in pixels*/
outFN = 'image' /*the filename of the output image PPM */
sWidth = 500; sHeight= 500 /*the screen width and height in pixels*/
call RGBfill red /*set the entire image to red. */
x= 10; y= 40 /*set pixel's coördinates. */
Call RGBfill red /*set the entire image to red. */
call RGBset x, y, blue /*set a pixel (at 10,40) to blue. */
x=10; y=40 /*set pixel's coördinates. */
color = RGBget(x, y) /*get the color of a pixel. */
Call RGBset x,y,blue /*set a pixel (at 10,40) to blue. */
hexV = c2x(color) /*get hex value of pixel's color. */
color = RGBget(x,y) /*get the color of a pixel. */
binV = x2b(hexV) /* " binary " " " " */
hexV = c2x(color) /*get hex value of pixel's color. */
binV = x2b(hexV) /* " binary " " " " */
bin3V = left(binV, 8) substr(binV, 9, 8) right(binV, 8)
hex3V = left(hexV, 2) substr(hexV, 3, 2) right(hexV, 2)
bin3V = left(binV,8) substr(binV,9,8) right(binV,8)
hex3V = left(hexV,2) substr(hexV,3,2) right(hexV,2)
xy= '(' || x","y')' /*create a handy─dandy literal for SAY.*/
say xy ' pixel in binary: ' binV /*show the binary value of 20,50 */
xy= '('||x','y')' /*create a handy-dandy literal for SAY.*/
say xy ' pixel in binary: ' bin3V /*show again, but with spaces. */
Say xy ' pixel in binary: ' binV /*show the binary value of 20,50 */
Say xy ' pixel in binary: ' bin3V /*show again,but with spaces. */
say /*show a blank between binary and hex. */
say xy ' pixel in hex: ' hexV /*show again, but in hexadecimal. */
Say /*show a blank between bin & hex. */
say xy ' pixel in hex: ' hex3V /*show again, but with spaces. */
Say xy ' pixel in hex: ' hexV /*show again,but in hexadecimal. */
Say xy ' pixel in hex: ' hex3V /*show again,but with spaces. */
call PPMwrite outFN, sWidth, sHeight /*create a PPM (output) file of image. */ /* ◄■■■■■■■■ not part of this task.*/
Call PPMwrite outFN,sWidth,sHeight /*create a PPM (output) file */
say /*show a blank. */
/* ?¦¦¦¦¦¦¦¦ not part of this task.*/
say 'The file ' outFN".PPM was created." /*inform user that a file was created. */
exit /*stick a fork in it, we're all done. */
Say /*show a blank. */
Say 'The file ' outFN'.PPM was created.' /*inform user */
/*──────────────────────────────────────────────────────────────────────────────────────*/
RGBfill: @.=arg(1); return /*fill image with a color.*/
Exit /*stick a fork in it, we're all done. */
/*---------------------------------------------------------------------*/
RGBget: parse arg px,py; return @.px.py /*get a pixel's color. */
RGBset: parse arg px,py,p$; @.px.py=p$; return /*set " " " */
RGBfill: pixel.=arg(1); Return /*fill image with a color.*/
RGBget: Parse arg px,py; Return pixel.px.py /*get a pixel's color. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
RGBset: Parse arg px,py,psep; pixel.px.py=psep; Return /*set a pixel */
PPMwrite: parse arg oFN, width, height /*obtain output filename, width, height*/
/*---------------------------------------------------------------------*/
oFID= oFN'.PPM'; $='9'x; #=255 /*fileID; separator; max color value.*/
PPMwrite: Parse arg oFN,width,height
call charout oFID, , 1 /*set the position of the file's output*/
call charout oFID,'P6'width || $ || height || $ || # || $ /*write hdr info.*/
oFID= oFN'.PPM' /* fileID */
do j=1 for width
sep='9'x; /* separator */
do k=1 for height; call charout oFID, @.j.k
maxcol=255 /* max color value. */
end /*k*/ /* ↑ write the PPM file, ··· */
Call charout oFID,,1 /*set the position of the file's output*/
Call charout oFID,'P6'width||sep||height||sep||maxcol||sep /* header */
end /*j*/ /* └───────── ··· one pixel at a time.*/
Do i=1 To width
call charout oFID; return /*close the output file just to be safe*/</lang>
Do j=1 To height;
Call charout oFID,pixel.i.j
End
End
Call charout oFID /* close the output file just to be safe */
Return</syntaxhighlight>
{{out|output}}
{{out|output}}
<pre>
<pre>
Line 3,896: Line 4,650:
===version 2===
===version 2===
This program actually creates a BMP file
This program actually creates a BMP file
<lang rexx>/* REXX ***************************************************************
<syntaxhighlight lang="rexx">/* REXX ***************************************************************
* Draw a picture from pixels
* Draw a picture from pixels
* 16.06.2014 Walter Pachl
* 16.06.2014 Walter Pachl
Line 4,006: Line 4,760:
i=w3*(y-1)+3*(x-1)
i=w3*(y-1)+3*(x-1)
say 'color at pixel' x'/'y'='c2x(substr(pic,i+1,3))
say 'color at pixel' x'/'y'='c2x(substr(pic,i+1,3))
Return c2x(substr(pic,i+1,3))</lang>
Return c2x(substr(pic,i+1,3))</syntaxhighlight>
{{out}}
{{out}}
<pre>lend: 600 -> 58020000 => 600
<pre>lend: 600 -> 58020000 => 600
Line 4,016: Line 4,770:


and have a look at the file pic.bmp created by this program</pre>
and have a look at the file pic.bmp created by this program</pre>

=={{header|Ruby}}==
=={{header|Ruby}}==
I haven't been able to find any kind of package for manipulating bitmap images, so let's roll one
I haven't been able to find any kind of package for manipulating bitmap images, so let's roll one
<lang ruby>class RGBColour
<syntaxhighlight lang="ruby">class RGBColour
def initialize(red, green, blue)
def initialize(red, green, blue)
unless red.between?(0,255) and green.between?(0,255) and blue.between?(0,255)
unless red.between?(0,255) and green.between?(0,255) and blue.between?(0,255)
Line 4,067: Line 4,820:
end
end
alias_method :set_pixel, :[]=
alias_method :set_pixel, :[]=
end</lang>
end</syntaxhighlight>

=={{header|Rust}}==
=={{header|Rust}}==
<lang Rust>#[derive(Copy, Clone, Debug, PartialEq, Eq)]
<syntaxhighlight lang="rust">#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Rgb {
pub struct Rgb {
pub r: u8,
pub r: u8,
Line 4,151: Line 4,903:
}
}
assert_eq!(Some(&Rgb::new(0, 155, 20)), image.get(3, 4));
assert_eq!(Some(&Rgb::new(0, 155, 20)), image.get(3, 4));
}</lang>
}</syntaxhighlight>

=={{header|Scala}}==
=={{header|Scala}}==
===Java translation===
===Java translation===
{{trans|Java}}
{{trans|Java}}
<lang scala>import java.awt.image.BufferedImage
<syntaxhighlight lang="scala">import java.awt.image.BufferedImage
import java.awt.Color
import java.awt.Color


Line 4,170: Line 4,921:
def setPixel(x:Int, y:Int, c:Color)=image.setRGB(x, y, c.getRGB())
def setPixel(x:Int, y:Int, c:Color)=image.setRGB(x, y, c.getRGB())
def getPixel(x:Int, y:Int)=new Color(image.getRGB(x, y))
def getPixel(x:Int, y:Int)=new Color(image.getRGB(x, y))
}</lang>
}</syntaxhighlight>
Usage:
Usage:
<lang scala>val img=new RgbBitmap(50, 50);
<syntaxhighlight lang="scala">val img=new RgbBitmap(50, 50);
img.fill(Color.CYAN)
img.fill(Color.CYAN)
img.setPixel(5, 5, Color.BLUE)
img.setPixel(5, 5, Color.BLUE)
Line 4,179: Line 4,930:
assert(img.getPixel(5,5)==Color.BLUE)
assert(img.getPixel(5,5)==Color.BLUE)
assert(img.width==50)
assert(img.width==50)
assert(img.height==50)</lang>
assert(img.height==50)</syntaxhighlight>
===Scala idiom===
===Scala idiom===
A more Scalesque version could be with the use of its idiom:
A more Scalesque version could be with the use of its idiom:
{{Out}}
{{Out}}
Best experienced in your browser [https://scastie.scala-lang.org/cy2uZB9DSaWVMnZjTJgQNA with Scastie (remote JVM)].
Best experienced in your browser [https://scastie.scala-lang.org/cy2uZB9DSaWVMnZjTJgQNA with Scastie (remote JVM)].
<lang scala>import java.awt.image.BufferedImage
<syntaxhighlight lang="scala">import java.awt.image.BufferedImage
import java.awt.Color
import java.awt.Color


Line 4,225: Line 4,976:
assert(img0.height == 60)
assert(img0.height == 60)
println("Tests successfully completed with no errors found.")
println("Tests successfully completed with no errors found.")
}</lang>
}</syntaxhighlight>

=={{header|Scheme}}==
=={{header|Scheme}}==
{{Works with|Scheme|R<math>^5</math>RS}}
{{Works with|Scheme|R<math>^5</math>RS}}


Definitions of list procedures:
Definitions of list procedures:
<lang scheme>(define (make-list length object)
<syntaxhighlight lang="scheme">(define (make-list length object)
(if (= length 0)
(if (= length 0)
(list)
(list)
Line 4,248: Line 4,998:
(if (= element 1)
(if (= element 1)
(car list)
(car list)
(list-get (cdr list) (- element 1))))</lang>
(list-get (cdr list) (- element 1))))</syntaxhighlight>
Definitions of image procedures:
Definitions of image procedures:
<lang scheme>(define (make-image columns rows)
<syntaxhighlight lang="scheme">(define (make-image columns rows)
(if (= rows 0)
(if (= rows 0)
(list)
(list)
Line 4,263: Line 5,013:


(define (image-get image column row)
(define (image-get image column row)
(list-get (list-get image row) column))</lang>
(list-get (list-get image row) column))</syntaxhighlight>
Definitions of some colours:
Definitions of some colours:
<lang scheme>(define *black* (list 0 0 0))
<syntaxhighlight lang="scheme">(define *black* (list 0 0 0))
(define *white* (list 255 255 255))
(define *white* (list 255 255 255))
(define *red* (list 255 0 0))
(define *red* (list 255 0 0))
(define *green* (list 0 255 0))
(define *green* (list 0 255 0))
(define *blue* (list 0 0 255))</lang>
(define *blue* (list 0 0 255))</syntaxhighlight>
This creates a small image with a black background and a single blue pixel:
This creates a small image with a black background and a single blue pixel:
<lang scheme>(define image (make-image 3 2))
<syntaxhighlight lang="scheme">(define image (make-image 3 2))
(image-fill! image *black*)
(image-fill! image *black*)
(image-set! image 2 1 *blue*)
(image-set! image 2 1 *blue*)
(display image)
(display image)
(newline)</lang>
(newline)</syntaxhighlight>
{{out}}
{{out}}
<lang>(((0 0 0) (0 0 255) (0 0 0)) ((0 0 0) (0 0 0) (0 0 0)))</lang>
<syntaxhighlight lang="text">(((0 0 0) (0 0 255) (0 0 0)) ((0 0 0) (0 0 0) (0 0 0)))</syntaxhighlight>

=={{header|Seed7}}==
=={{header|Seed7}}==
The types and functions requested are predefined in the libraries
The types and functions requested are predefined in the libraries
Line 4,289: Line 5,038:
*The color of a pixel can be retrieved with [http://seed7.sourceforge.net/libraries/draw.htm#getPixelColor(in_PRIMITIVE_WINDOW,in_integer,in_integer) getPixelColor].
*The color of a pixel can be retrieved with [http://seed7.sourceforge.net/libraries/draw.htm#getPixelColor(in_PRIMITIVE_WINDOW,in_integer,in_integer) getPixelColor].


<lang seed7>$ include "seed7_05.s7i";
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "draw.s7i";
include "draw.s7i";


Line 4,302: Line 5,051:
myColor := getPixelColor(myPixmap, 20, 30);
myColor := getPixelColor(myPixmap, 20, 30);
writeln(myColor.redLight <& " " <& myColor.greenLight <& " " <& myColor.blueLight);
writeln(myColor.redLight <& " " <& myColor.greenLight <& " " <& myColor.blueLight);
end func;</lang>
end func;</syntaxhighlight>

=={{header|SequenceL}}==
=={{header|SequenceL}}==
<lang seed7>RGB ::= (R: int(0), G: int(0), B: int(0));
<syntaxhighlight lang="seed7">RGB ::= (R: int(0), G: int(0), B: int(0));


newBitmap: int * int -> RGB(2);
newBitmap: int * int -> RGB(2);
Line 4,342: Line 5,090:
redCenter := setColorAt(filledGreen, width / 2, height / 2, lightRed);
redCenter := setColorAt(filledGreen, width / 2, height / 2, lightRed);
in
in
getColorAt(redCenter, width / 2, height / 2);</lang>
getColorAt(redCenter, width / 2, height / 2);</syntaxhighlight>


{{out}}
{{out}}
<pre>cmd:> main.exe
<pre>cmd:> main.exe
(B:51,G:51,R:255)</pre>
(B:51,G:51,R:255)</pre>

=={{header|Smalltalk}}==
=={{header|Smalltalk}}==
{{works with|Smalltalk/X}}
{{works with|Smalltalk/X}}
<lang Smalltalk>|img1 img2|
<syntaxhighlight lang="smalltalk">|img1 img2|
"a depth24 RGB image"
"a depth24 RGB image"
img1 := Image width:100 height:200 depth:24.
img1 := Image width:100 height:200 depth:24.
Line 4,371: Line 5,118:
img2 displayOn:Transcript window graphicsContext.
img2 displayOn:Transcript window graphicsContext.
Transcript showCR:(img2 colorAt:(100 @ 10) ).
Transcript showCR:(img2 colorAt:(100 @ 10) ).
</syntaxhighlight>
</lang>

=={{header|Tcl}}==
=={{header|Tcl}}==
{{libheader|Tk}}
{{libheader|Tk}}
<lang tcl>package require Tcl 8.5
<syntaxhighlight lang="tcl">package require Tcl 8.5
package require Tk
package require Tk
namespace path ::tcl::mathfunc ;# for [max] function
namespace path ::tcl::mathfunc ;# for [max] function
Line 4,404: Line 5,150:
setPixel $img green {40 40}
setPixel $img green {40 40}


set rbg [getPixel $img {40 40}]</lang>
set rbg [getPixel $img {40 40}]</syntaxhighlight>

=={{header|TI-89 BASIC}}==
=={{header|TI-89 BASIC}}==


TI-89 BASIC does not have user-defined data structures. The Rosetta Code tasks which use this image type have instead been implemented using the TI-89's graph screen.
TI-89 BASIC does not have user-defined data structures. The Rosetta Code tasks which use this image type have instead been implemented using the TI-89's graph screen.

=={{header|UNIX Shell}}==
=={{header|UNIX Shell}}==
{{works with|ksh93}}
{{works with|ksh93}}
<lang bash>typeset -T RGBColor_t=(
<syntaxhighlight lang="bash">typeset -T RGBColor_t=(
integer r g b
integer r g b
function to_s {
function to_s {
Line 4,485: Line 5,229:
b.setpixel 2 1 "$(color.black)"
b.setpixel 2 1 "$(color.black)"
echo "$(b.getpixel 0 0)"
echo "$(b.getpixel 0 0)"
b.to_s</lang>
b.to_s</syntaxhighlight>


{{out}}
{{out}}
Line 4,494: Line 5,238:
255 0 0 0 255 0 0 0 255
255 0 0 0 255 0 0 0 255
255 255 0 255 255 255 0 0 0</pre>
255 255 0 255 255 255 0 0 0</pre>

=={{header|Vedit macro language}}==
=={{header|Vedit macro language}}==


An edit buffer is used to store pixel data. In order to allow unlimited image size, a temporary file (here pixel.data) can be assosicated to the buffer. You could directly open the image file you are creating (as in the task [[Dragon_curve#Vedit_macro_language|Dragon_curve]], but here we first create just the plain pixel data so that the required image file format can be decided later.
An edit buffer is used to store pixel data. In order to allow unlimited image size, a temporary file (here pixel.data) can be assosicated to the buffer. You could directly open the image file you are creating (as in the task [[Dragon_curve#Vedit_macro_language|Dragon_curve]], but here we first create just the plain pixel data so that the required image file format can be decided later.
<lang vedit>#11 = 400 // Width of the image
<syntaxhighlight lang="vedit">#11 = 400 // Width of the image
#12 = 300 // Height of the image
#12 = 300 // Height of the image


Line 4,564: Line 5,307:
#6 = Cur_Char(1)
#6 = Cur_Char(1)
#7 = Cur_Char(2)
#7 = Cur_Char(2)
Return</lang>
Return</syntaxhighlight>

=={{header|Visual Basic .NET}}==
=={{header|Visual Basic .NET}}==


<lang vbnet>' The StructLayout attribute allows fields to overlap in memory.
<syntaxhighlight lang="vbnet">' The StructLayout attribute allows fields to overlap in memory.
<System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)> _
<System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)> _
Public Structure Rgb
Public Structure Rgb
Line 4,590: Line 5,332:
End Sub
End Sub


End Structure</lang>
End Structure</syntaxhighlight>


<lang vbnet>Public Class RasterBitmap
<syntaxhighlight lang="vbnet">Public Class RasterBitmap


Private m_pixels() As Rgb
Private m_pixels() As Rgb
Line 4,630: Line 5,372:
End Function
End Function


End Class</lang>
End Class</syntaxhighlight>

=={{header|Wren}}==
=={{header|Wren}}==
{{libheader|DOME}}
{{libheader|DOME}}
The above library's ImageData class fits the bill here (version 1.3.0 or later).
The above library's ImageData class fits the bill here (version 1.3.0 or later).
<lang ecmascript>import "graphics" for Canvas, ImageData, Color
<syntaxhighlight lang="wren">import "graphics" for Canvas, ImageData, Color
import "dome" for Window
import "dome" for Window


Line 4,668: Line 5,409:


static draw(alpha) {}
static draw(alpha) {}
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 4,677: Line 5,418:
=={{header|Xojo}}==
=={{header|Xojo}}==


<lang vb>Function CreatePicture(width As Integer, height As Integer) As Picture
<syntaxhighlight lang="vb">Function CreatePicture(width As Integer, height As Integer) As Picture
Return New Picture(width, height)
Return New Picture(width, height)
End Function
End Function
Line 4,693: Line 5,434:
p.RGBSurface.Pixel(x, y) = pColor
p.RGBSurface.Pixel(x, y) = pColor
End Sub
End Sub
</syntaxhighlight>
</lang>

=={{header|XPL0}}==
=={{header|XPL0}}==
[[File:BitmapXPL0.png|right]]
[[File:BitmapXPL0.png|right]]
<lang XPL0>include c:\cxpl\codes; \include 'code' declarations
<syntaxhighlight lang="xpl0">include c:\cxpl\codes; \include 'code' declarations
def Width=180, Height=135, Color=$123456;
def Width=180, Height=135, Color=$123456;
int X, Y;
int X, Y;
Line 4,707: Line 5,447:
X:= ChIn(1); \wait for keystroke
X:= ChIn(1); \wait for keystroke
SetVid(3); \restore display to normal text mode
SetVid(3); \restore display to normal text mode
]</lang>
]</syntaxhighlight>
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">// Rosetta Code problem: http://rosettacode.org/wiki/Bitmap
// by Galileo, 07/2022


open window 200, 200
backcolor 255, 0, 0 // red

clear window

color 0, 255, 0 // green
dot 100, 100

c$ = getbit$(100, 100, 100, 100) // get color area 1x1 pixel
print c$
</syntaxhighlight>
{{out}}
<pre>rgb 1,1:00ff00
---Program done, press RETURN---</pre>
=={{header|zkl}}==
=={{header|zkl}}==
This solution creates a PPM image. No error checking or clipping.
This solution creates a PPM image. No error checking or clipping.
<lang zkl>class PPM{ // (0,0) is logically bottom left
<syntaxhighlight lang="zkl">class PPM{ // (0,0) is logically bottom left
fcn init(width,height){
fcn init(width,height){
sz:=width*height*3;
sz:=width*height*3;
Line 4,729: Line 5,486:
out.close();
out.close();
}
}
}</lang>
}</syntaxhighlight>
<lang zkl>ppm:=PPM(256,256);
<syntaxhighlight lang="zkl">ppm:=PPM(256,256);
ppm.fill(0x00FF88);
ppm.fill(0x00FF88);
foreach x in ([50..200]){ ppm[x,50]=0xff|00|00; } // horizontal red line
foreach x in ([50..200]){ ppm[x,50]=0xff|00|00; } // horizontal red line


ppm.write(File("foo.ppm","wb"));</lang>
ppm.write(File("foo.ppm","wb"));</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 4,746: Line 5,503:
...
...
</pre>
</pre>
{{omit from|AWK}}
{{omit from|PARI/GP}}

Latest revision as of 09:59, 8 November 2023

Task
Bitmap
You are encouraged to solve this task according to the task description, using any language you may know.

Show a basic storage type to handle a simple RGB raster graphics image, and some primitive associated functions.

If possible provide a function to allocate an uninitialised image, given its width and height, and provide 3 additional functions:

  •   one to fill an image with a plain RGB color,
  •   one to set a given pixel with a color,
  •   one to get the color of a pixel.


(If there are specificities about the storage or the allocation, explain those.)

These functions are used as a base for the articles in the category raster graphics operations, and a basic output function to check the results is available in the article write ppm file.

11l

Translation of: Python
T Colour
   Byte r, g, b

   F (r, g, b)
      .r = r
      .g = g
      .b = b

   F ==(other)
      R .r == other.r & .g == other.g & .b == other.b

V black = Colour(0, 0, 0)
V white = Colour(255, 255, 255)

T Bitmap
   Int width, height
   Colour background
   [[Colour]] map

   F (width = 40, height = 40, background = white)
      assert(width > 0 & height > 0)
      .width = width
      .height = height
      .background = background
      .map = [[background] * width] * height

   F fillrect(x, y, width, height, colour = black)
      assert(x >= 0 & y >= 0 & width > 0 & height > 0)
      L(h) 0 .< height
         L(w) 0 .< width
            .map[y + h][x + w] = colour

   F chardisplay()
      V txt = .map.map(row -> row.map(bit -> (I bit == @@.background {‘ ’} E ‘@’)).join(‘’))
      txt = txt.map(row -> ‘|’row‘|’)
      txt.insert(0, ‘+’(‘-’ * .width)‘+’)
      txt.append(‘+’(‘-’ * .width)‘+’)
      print(reversed(txt).join("\n"))

   F set(x, y, colour = black)
      .map[y][x] = colour

   F get(x, y)
      R .map[y][x]

V bitmap = Bitmap(20, 10)
bitmap.fillrect(4, 5, 6, 3)
assert(bitmap.get(5, 5) == black)
assert(bitmap.get(0, 1) == white)
bitmap.set(0, 1, black)
assert(bitmap.get(0, 1) == black)
bitmap.chardisplay()
Output:
+--------------------+
|                    |
|                    |
|    @@@@@@          |
|    @@@@@@          |
|    @@@@@@          |
|                    |
|                    |
|                    |
|@                   |
|                    |
+--------------------+

Action!

Part of the solution can be found in RGBIMAGE.ACT

INCLUDE "H6:RGBIMAGE.ACT" ;from task Bitmap

RGB black,yellow,violet,blue

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

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

PROC Main()
  RgbImage img
  BYTE CH=$02FC,width=[80],height=[60]
  BYTE ARRAY ptr(14400)
  BYTE i,x,y,c

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

  RgbBlack(black)
  RgbYellow(yellow)
  RgbViolet(violet)
  RgbBlue(blue)

  InitRgbImage(img,width,height,ptr)
  FillRgbImage(img,blue)

  FOR i=1 TO 1000
  DO
    c=Rand(3)
    x=Rand(width)
    y=Rand(height)
    IF c=0 THEN
      SetRgbPixel(img,x,y,yellow)
    ELSEIF c=1 THEN
      SetRgbPixel(img,x,y,violet)
    ELSE
      SetRgbPixel(img,x,y,black)
    FI
  OD

  DrawImage(img,(160-width)/2,(96-height)/2)

  DO UNTIL CH#$FF OD
  CH=$FF
RETURN
Output:

Screenshot from Atari 8-bit computer

ActionScript

ActionScript 3 has a BitmapData class (in the flash.display package) which can be used for storage and handling of bitmap images. To display these images, the Bitmap class can be used.

// To import the BitmapData class:
import flash.display.BitmapData;

// Creates a new BitmapData object with a width of 500 pixels and a height of 300 pixels.
var bitmap:BitmapData = new BitmapData(500, 300);

// Create a BitmapData with transparency disallowed
var opaqueBitmap:BitmapData = new BitmapData(500, 300, false);

// Bitmap with initial fill colour, as 0xAARRGGBB (default is white)
var redFilledBitmap:BitmapData = new BitmapData(400, 300, true, 0xFFFF0000);

// Get the colour value of the pixel at point (200, 200)
bitmap.getPixel(200, 200)     // As 0xRRGGBB
bitmap.getPixel32(200, 200)   // As 0xAARRGGBB

// Set the colour value of the pixel at point (300, 200) to blue
bitmap.setPixel(300, 200, 0x0000FF);       // As 0xRRGGBB
bitmap.setPixel32(300, 200, 0xFF0000FF);   // As 0xAARRGGBB

// Fill the bitmap with a given colour (as 0xAARRGGBB) after construction
bitmap.fillRect(bitmap.rect, 0xFF44FF44);

Ada

The package interface:

package Bitmap_Store is
   type Luminance is mod 2**8;
   type Pixel is record
      R, G, B : Luminance := Luminance'First;
   end record;
   Black : constant Pixel := (others => Luminance'First);
   White : constant Pixel := (others => Luminance'Last);
   type Image is array (Positive range <>, Positive range <>) of Pixel;
 
   procedure Fill (Picture : in out Image; Color : Pixel);
 
   procedure Print (Picture : Image);
 
   type Point is record
      X, Y : Positive;
   end record;
end Bitmap_Store;

The implementation of:

with Ada.Text_IO;  use Ada.Text_IO;

package body Bitmap_Store is

   procedure Fill (Picture : in out Image; Color : Pixel) is
   begin
      for p of Picture loop x:= Color;end loop;
   end Fill;
 
   procedure Print (Picture : Image) is
   begin
      for I in Picture'Range (1) loop
         for J in Picture'Range (2) loop
               Put (if Picture (I, J) = White then ' ' else 'H');
         end loop;
         New_Line;
      end loop; 
   end Print;

end Bitmap_Store;

This can be used like:

use Bitmap_Store;  with Bitmap_Store;
   ...
   X : Image (1..64, 1..64);
begin
   Fill (X, (255, 255, 255));
   X (1, 2) := (R => 255, others => 0);
   X (3, 4) := X (1, 2);

ALGOL 68

Translation of: ada

Note: short and shorten need to be tuned (added or removed) to match the underlying graphic hardware colour depth.

Works with: ALGOL 68 version Revision 1 - one minor extension to language used - PRAGMA READ, similar to C's #include directive.
Works with: ALGOL 68G version Any - tested with release algol68g-2.6.

File: prelude/Bitmap.a68

# -*- coding: utf-8 -*- #

MODE PIXEL = STRUCT(#SHORT# BITS red,green,blue);
MODE POINT = STRUCT(INT x,y);

MODE IMAGE = [0,0]PIXEL; # instance attributes #

MODE CLASSIMAGE = STRUCT ( # class attributes #
  PIXEL black, red, green, blue, white,
  PROC (REF IMAGE)REF IMAGE init,
  PROC (REF IMAGE, PIXEL)VOID fill,
  PROC (REF IMAGE)VOID print,
# virtual: #
  REF PROC (REF IMAGE, POINT, POINT, PIXEL)VOID line,
  REF PROC (REF IMAGE, POINT, INT, PIXEL)VOID circle,
  REF PROC (REF IMAGE, POINT, POINT, POINT, POINT, PIXEL, UNION(INT, VOID))VOID cubic bezier
);

CLASSIMAGE class image = (
  # black = # (#SHORTEN# 16r00, #SHORTEN# 16r00, #SHORTEN# 16r00),
  # red   = # (#SHORTEN# 16rff, #SHORTEN# 16r00, #SHORTEN# 16r00),
  # green = # (#SHORTEN# 16r00, #SHORTEN# 16rff, #SHORTEN# 16r00),
  # blue  = # (#SHORTEN# 16r00, #SHORTEN# 16r00, #SHORTEN# 16rff),
  # white = # (#SHORTEN# 16rff, #SHORTEN# 16rff, #SHORTEN# 16rff),
  # PROC init = # (REF IMAGE self)REF IMAGE:
    BEGIN
      (fill OF class image)(self, black OF class image);
      self
    END,

  # PROC fill = # (REF IMAGE self, PIXEL color)VOID:
      FOR x FROM 1 LWB self TO 1 UPB self DO
        FOR y FROM 2 LWB self TO 2 UPB self DO
          self[x,y] := color
        OD
      OD,
  # PROC print = # (REF IMAGE self)VOID:
      printf(($n(UPB self)(3(16r2d))l$, self)),
# virtual: #
  # REF PROC line = # LOC PROC (REF IMAGE, POINT, POINT, PIXEL)VOID,
  # REF PROC circle = # LOC PROC (REF IMAGE, POINT, INT, PIXEL)VOID,
  # REF PROC cubic bezier = # LOC PROC (REF IMAGE, POINT, POINT, POINT, POINT, PIXEL, UNION(INT, VOID))VOID
);

OP CLASSOF = (IMAGE image)CLASSIMAGE: class image;
OP INIT = (REF IMAGE image)REF IMAGE: (init OF (CLASSOF image))(image);

SKIP

File: test/Bitmap.a68

#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #

### The test program ###
PR READ "prelude/Bitmap.a68" PR;

test:(
   REF IMAGE x := INIT LOC[1:16, 1:16]PIXEL;
   (fill OF class image) (x, white OF class image);
   (print OF class image) (x)
)
Output:

(A 16x16 white block)

ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Applesoft BASIC

The Bitmap Address (BA) of the image is 24576 in order to maximize available space for the image without clobbering hi-res graphics memory. Just enough room is allocated for a P6 header. The Bitmap Beginning (BB) is just after the header.

HIMEM is set to 8192 which is just below hi-res graphics memory. It isn't necessary to protect hi-res graphics memory, but it doesn't hurt. Larger images can be allocated by using a lower Bitmap Address.

 100 W = 8
 110 H = 8
 120 BB = 24576 +  LEN ( STR$ (W) +  STR$ (H)) + 9: REM  P6 HEADER
 130  HIMEM: 8192
 140 R = 255
 150 G = 255
 160 B = 0
 170 C = R + G * 256 + B * 65536
 180  GOSUB 600FILL
 190 X = 4
 200 Y = 5
 210 R = 127
 220 G = 127
 230 B = 255
 240 C = R + G * 256 + B * 65536
 250  GOSUB 500"SET PIXEL"
 260 X = 3
 270 Y = 2
 280  GOSUB 400"GET PIXEL"
 290  PRINT "COLOR="C" RED="R" GREEN="G" BLUE="B;
 300  END 
 400 A = BB + X * 3 + Y * W * 3
 410 R =  PEEK (A)
 420 G =  PEEK (A + 1)
 430 B =  PEEK (A + 2)
 440 C = R + G * 256 + B * 65536
 450  RETURN 
 500 R = C -  INT (C / 256) * 256
 510 B =  INT (C / 65536)
 520 G =  INT (C / 256) - B * 256
 530 A = BB + X * 3 + Y * W * 3
 540  POKE A,R
 550  POKE A + 1,G
 560  POKE A + 2,B
 570  RETURN 
 600  FOR Y = 0 TO H - 1
 610      FOR X = 0 TO W - 1
 620          GOSUB 500"SET PIXEL"
 630          NEXT X,Y
 640  RETURN

ARM Assembly

Works with: Game Boy Advance

The Game Boy Advance's video memory is located at address 0x06000000, and is 240 pixels by 160 pixels, with 16 bits defining the color of each pixel. This is a linear array of memory; storing 0xFFFF at 0x06000000 for example will immediately make the top-left pixel of the screen turn white. The following routines are intended for the bitmap screen modes, and have only been tested in screen mode 3. There is no need to allocate this video memory as it is always available thanks to the hardware.

Bitmap_FloodFill:
	;input:
	;r0 = color to fill screen with (15-bit color)
	STMFD sp!,{r0-r12,lr}
			
			MOV R2,#160
			MOV R4,#0x06000000
outerloop_floodfill:
			MOV R1,#240               ;restore inner loop counter
innerloop_floodfill:
			strH r0,[r4] 
			add r4,r4,#2              ;next pixel
			subs r1,r1,#1             ;decrement loop counter
			bne innerloop_floodfill
			subs r2,r2,#1
			bne outerloop_floodfill
	
	LDMFD sp!,{r0-r12,pc}
	
Bitmap_Locate:
        ;given x and y coordinates, offsets vram addr to that pixel on screen.
	;input: 
	;r0 = x
	;r1 = y
	;output: r2 = vram area
	STMFD sp!,{r4-r12,lr}
		mov r2,#0x06000000	;vram base

		
		mov r4,#240*2          ;240 pixels across, 2 bytes per pixel
		mul r1,r4,r1
		add r2,r2,r1          ;add y*480
		add r2,r2,r0,lsl #1   ;add x*2
	LDMFD sp!,{r4-r12,pc}
	
Bitmap_StorePixel:
	;input: r3 = color
	;r0 = x
	;r1 = y
	bl Bitmap_Locate
	strH r3,[r2]                 ;store the pixel color in video memory
	bx lr
	
Bitmap_GetPixel:
        ;retrieves the color of the pixel at [r2] and stores its color value in r3.
	;r0 = x
	;r1 = y
	;output in r3
	bl Bitmap_Locate
	ldrH r3,[r2]
	bx lr

ATS

Because this code will be used in other tasks, I have separated it into "static" and "dynamic" source files. The former is the equivalent of an "interface" file in some other languages, and the latter is equivalent of an "implementation" file. I included some test code that gets compiled if you put the correct option on the compiler command line.

The ATS static file

This file should be called bitmap_task.sats.

#define ATS_PACKNAME "Rosetta_Code.bitmap_task"

(*------------------------------------------------------------------*)

(* I am going to do this at the most primitive level. So here is the
   "abstractified" type, or really a whole set of different types:
   w-by-h pixmap of values of type a, with pixel storage at address
   p. The type is linear (‘use it once and only once’). We will make
   pixmap a boxed type, so its size will be equal to that of a
   pointer. (This is actually a general 2-dimensional array type!
   But let us ignore that.) *)
absvtype pixmap (a : t@ype, w : int, h : int, p : addr) = ptr

(* A shorthand for a pixmap with its pixel storage at "some"
   address. *)
vtypedef pixmap (a : t@ype, w : int, h : int) =
  [p : addr] pixmap (a, w, h, p)

(* A shorthand for a pixmap with "some" width and height, and with its
   pixel storage at "some" address. *)
vtypedef pixmap (a : t@ype) = [w, h : int] pixmap (a, w, h)

(* A shorthand for a pixmap with "some" POSITIVE width and POSITIVE
   height, and with its pixel storage at "some" address. *)
vtypedef pixmap1 (a : t@ype) = [w, h : pos] pixmap (a, w, h)

(*------------------------------------------------------------------*)
(* Here are definitions for a small set of operations, including the
   ones requested in the task document.

   But note that, in ATS, we are careful about uninitialized data. It
   is POSSIBLE to create an uninitialized pixmap, but NOT possible to
   set or get individual pixels, if the pixmap is not already fully
   initialized by some other means (such as "fill" or "load"). *)

fn {}
pixmap_width :
  {a    : t@ype}
  {w, h : int}
  (!pixmap (a, w, h)) -<> size_t w

fn {}
pixmap_height :
  {a    : t@ype}
  {w, h : int}
  (!pixmap (a, w, h)) -<> size_t h

fn {a : t@ype}
pixmap_make_array :
  (* Make a new pixmap from an existing array. The array may be
     anywhere (for instance, a stack frame or the heap), and need not
     be initialized. *)
  {w, h : int} {p : addr}
  (array_v (a, p, w * h) | size_t w, size_t h, ptr p) ->
    pixmap (a, w, h, p)

fn {a : t@ype}
pixmap_unmake :
  (* Essentially the reverse of pixmap_make_array. Temporarily treat a
     pixmap as an array. The array will be organized as rows from left
     to right, with the rows themselves going from top to bottom. Thus
     an index would be i = x + (y * w). *)
  {w, h : int} {p : addr}
  pixmap (a, w, h, p) ->
    @(array_v (a, p, w * h) | size_t w, size_t h, ptr p)

prfn
pixmap_prove_index_bounds :
  (* A proof that i = x + (y * w) is within bounds of the array
     returned by pixmap_unmake. *)
  {w, h : int}
  {x, y : nat | x < w; y < h}
  () -<prf>
    [0 <= x + (y * w);
     x + (y * w) < w * h]
     void

fn {a : t@ype}
pixmap_make_uninitized :
  (* Make a new uninitialized pixmap, with the pixels stored in the
     heap. *)
  {w, h : int}
  (size_t w, size_t h) ->
    [p : addr | null < p] @(mfree_gc_v p | pixmap (a?, w, h, p))

fn {a : t@ype}
pixmap_make_elt :
  (* Make a new pixmap, initialized with a given element, with the
     pixels stored in the heap. *)
  {w, h : int}
  (size_t w, size_t h, a) ->
    [p : addr | null < p] @(mfree_gc_v p | pixmap (a, w, h, p))

fn {}
pixmap_free_storage_return :
  (* Free a pixmap, returning the storage array to the user. *)
  {a : t@ype}
  {w, h : int} {p : addr}
  pixmap (a, w, h, p) -> @(array_v (a, p, w * h) | ptr p)

fn {}
pixmap_free_storage_free :
  (* If a pixmap's pixels were allocated in the heap, then free its
     storage. *)
  {a : t@ype}
  {w, h : int} {p : addr}
  (mfree_gc_v p | pixmap (a, w, h, p)) -> void

fn {a : t@ype}
pixmap_fill_elt :
  (* Fill a pixmap with the given element. (Technically speaking, the
     value of the first argument is consumed, and replaced by a new
     value. Its type before and after is linear.) *)
  {w, h : int} {p : addr}
  (* The question mark means that the pixmap elements can start out
     uninitialized. *)
  (!pixmap (a?, w, h, p) >> pixmap (a, w, h, p), a) -> void

fn {a  : t@ype}
          {tk : tkind}
pixmap_set_at_guint :
  (* Set a pixel at unsigned integer coordinates. You can do this only
     on a pixmap that has been initialized. (It would be prohibitively
     tedious to safely work with randomly located pixels, if the array
     were not already fully initialized.) *)
  {w, h : int}
  {x, y : int | x < w; y < h}
  (!pixmap (a, w, h), g1uint (tk, x), g1uint (tk, y), a) -> void

fn {a  : t@ype}
          {tk : tkind}
pixmap_set_at_gint :
  (* Set a pixel, but with signed integer coordinates. *)
  {w, h : int}
  {x, y : nat | x < w; y < h}
  (!pixmap (a, w, h), g1int (tk, x), g1int (tk, y), a) -> void

fn {a : t@ype} {tk : tkind}
pixmap_get_at_guint :
  (* Get a pixel at unsigned integer coordinates. You can do this only
     on a pixmap that has been initialized. *)
  {w, h : int}
  {x, y : int | x < w; y < h}
  (!pixmap (a, w, h), g1uint (tk, x), g1uint (tk, y)) -> a

fn {a : t@ype} {tk : tkind}
pixmap_get_at_gint :
  (* Get a pixel, but with signed integer coordinates. *)
  {w, h : int}
  {x, y : nat | x < w; y < h}
  (!pixmap (a, w, h), g1int (tk, x), g1int (tk, y)) -> a

fn {a : t@ype}
pixmap_dump :
  (* Dump the contents of a pixmap to an output stream, row by row as
     in a PPM. You must implement the pixmap$pixels_dump template
     function. (We are anticipating the task to write a PPM file, and
     wish to do it in a nice way. I am likely to end up actually using
     this code, after all.) *)
  {w, h : int}
  (* I return a success-or-failure value, to avoid committing to using
     an exception here. There are circumstances in which exceptions are
     not the best approach. *)
  (FILEref, !pixmap (a, w, h)) -> bool (* success *)

fn {a : t@ype}
pixmap$pixels_dump :
  (* A function that the writes n pixels to an output stream. (It
     could be one pixel, it could be the entire image. From the user's
     standpoint, it makes no difference. It is an implementation
     detail HOW the function is called by pixmap_dump.) *)
  {n : int}
  (FILEref, &array (a, n), size_t n) -> bool (* success *)

fn {a : t@ype}
pixmap_load :
  (* Load the contents of a pixmap from an input stream, row by row as
     in a PPM. You must implement the pixmap$pixels_load template
     function. A value of type a has to be given, to initialize the
     array with if the loading fails. *)
  {w, h : int} {p : addr}
  (FILEref, !pixmap (a?, w, h, p) >> pixmap (a, w, h, p), a) ->
    bool (* success *)

fn {a : t@ype}
pixmap$pixels_load :
  (* A function that the reads n pixels from an input stream. (It
     could be one pixel, it could be the entire image. From the user's
     standpoint, it makes no difference. It is an implementation
     detail HOW the function is called by pixmap_load.) *)
  {n : int}
  (FILEref, &array (a?, n) >> array (a, n), size_t n, a) ->
    bool (* success *)

overload pixmap_make with pixmap_make_array
overload pixmap_make with pixmap_make_uninitized
overload pixmap_make with pixmap_make_elt

overload pixmap_free with pixmap_free_storage_return
overload pixmap_free with pixmap_free_storage_free
overload free with pixmap_free_storage_free

overload fill with pixmap_fill_elt

overload pixmap_set_at with pixmap_set_at_guint
overload pixmap_set_at with pixmap_set_at_gint
overload [] with pixmap_set_at

overload pixmap_get_at with pixmap_get_at_guint
overload pixmap_get_at with pixmap_get_at_gint
overload [] with pixmap_get_at

overload dump with pixmap_dump
overload load with pixmap_load

overload width with pixmap_width
overload height with pixmap_height

(*------------------------------------------------------------------*)
(* Here is a type for 24-bit RGB data. An RGB pixmap type thus can be
   written as "pixmap (rgb24, w, h, p)".
   
   There are, though you cannot see it here (they are in the dynamic
   file), default implementations of pixmap$pixels_dump<rgb24> and
   pixmap$pixels_load<rgb24>. These implementations are for dumping
   raw data in PPM format. *)

(* It is an abstract type, the size of a triple of uint8. (It is, in
   fact, a triple of uint8, but we hide this fact, so the template
   system will not confuse the type with other triples of uint8. It is
   a subtle matter. *)
abst@ype rgb24 = @(uint8, uint8, uint8)

fn {tk : tkind}
rgb24_make_uint_uint_uint :
  (g0uint tk, g0uint tk, g0uint tk) -<> rgb24

fn {tk : tkind}
rgb24_make_int_int_int :
  (g0int tk, g0int tk, g0int tk) -<> rgb24

fn {}
rgb24_make_tuple : @(uint8, uint8, uint8) -<> rgb24

fn {}
rgb24_values : rgb24 -<> @(uint8, uint8, uint8)

overload rgb24_make with rgb24_make_uint_uint_uint
overload rgb24_make with rgb24_make_int_int_int
overload rgb24_make with rgb24_make_tuple

(*------------------------------------------------------------------*)

The ATS dynamic file

This file should be called bitmap_task.dats.

(*------------------------------------------------------------------*)

#define ATS_DYNLOADFLAG 0
#define ATS_PACKNAME "Rosetta_Code.bitmap_task"

#include "share/atspre_staload.hats"

staload "bitmap_task.sats"

(*------------------------------------------------------------------*)

(* The actual type, normally not seen by the user, is a boxed
   record. *)
datavtype _pixmap (a : t@ype, w : int, h : int, p : addr) =
| _pixmap of
    @{
      pf = array_v (a, p, w * h) |
      w  = size_t w,
      h  = size_t h,
      p  = ptr p
    }

(* Here is one of the ways to tie an abstract type to its
   implementation: *)
assume pixmap (a, w, h, p) = _pixmap (a, w, h, p)
(* Another way is to use casts. *)

(*------------------------------------------------------------------*)

implement {}
pixmap_width pix =
  case+ pix of _pixmap record => record.w

implement {}
pixmap_height pix =
  case+ pix of _pixmap record => record.h

implement {a}
pixmap_make_array (pf | w, h, p) =
  _pixmap @{pf = pf | w = w, h = h, p = p}

implement {a}
pixmap_unmake pix =
  case+ pix of
  | ~ _pixmap @{pf = pf | w = w, h = h, p = p} => @(pf | w, h, p)

primplement
pixmap_prove_index_bounds {w, h} {x, y} () =
  let
    prval () = mul_gte_gte_gte {y, w} ()
    prval () = mul_gte_gte_gte {h - (y + 1), w} ()
  in
  end

implement {a}
pixmap_make_uninitized {w, h} (w, h) =
  let
    prval () = lemma_g1uint_param w      (* Proves w >= 0. *)
    prval () = lemma_g1uint_param h      (* Proves h >= 0. *)
    prval () = mul_gte_gte_gte {w, h} () (* Proves w*h >= 0. *)

    val @(pf, pfgc | p) = array_ptr_alloc<a> (w * h)
    val pix = pixmap_make<a?> (pf | w, h, p)
  in
    @(pfgc | pix)
  end

implement {a}
pixmap_make_elt (w, h, elt) =
  let
    val @(pfgc | pix) = pixmap_make<a> (w, h)
  in
    fill<a> (pix, elt);
    @(pfgc | pix)
  end

implement {}
pixmap_free_storage_return pix =
  case+ pix of
  | ~ _pixmap record => @(record.pf | record.p)

implement {}
pixmap_free_storage_free (pfgc | pix) =
  let
    val @(pf | p) = pixmap_free pix
  in
    array_ptr_free (pf, pfgc | p)
  end

implement {a}
pixmap_fill_elt {w, h} {p} (pix, elt) =
  case+ pix of
  | @ _pixmap record =>
    let
      prval () = lemma_g1uint_param (record.w)
      prval () = lemma_g1uint_param (record.h)
      prval () = mul_gte_gte_gte {w, h} ()
      stadef n = w * h
      val n : size_t n = record.w * record.h
      and p : ptr p = record.p

      fun
      loop {i : nat | i <= n}
           .<n - i>.
           (pf_lft : array_v (a, p, i),
            pf_rgt : array_v (a?, p + (i * sizeof a), n - i) |
            i      : size_t i)
          : @(array_v (a, p, n) | ) =
        if i = n then
          let
            prval () = array_v_unnil pf_rgt
          in
            @(pf_lft | )
          end
        else
          let
            prval @(pf_elt, pf_rgt) = array_v_uncons pf_rgt
            val () = ptr_set<a> (pf_elt | ptr_add<a> (p, i), elt)
            prval pf_lft = array_v_extend (pf_lft, pf_elt)
          in
            loop (pf_lft, pf_rgt | succ i)
          end

      val @(pf | ) = loop (array_v_nil (), record.pf | i2sz 0)
      prval () = record.pf := pf
      prval () = fold@ pix
    in
    end

implement {a} {tk}
pixmap_set_at_guint {w, h} {x, y} (pix, x, y, elt) =
  case+ pix of
  | @ _pixmap record =>
    let
      prval () = lemma_g1uint_param x
      prval () = lemma_g1uint_param y

      stadef n = w * h
      stadef i = x + (y * w)

      prval () = pixmap_prove_index_bounds {w, h} {x, y} ()
      prval () = prop_verify {0 <= i && i < n} ()

      (* I purposely store the data in an order such that you can
         write something such as a PPM without looping separately
         over x and y. Also, even if you did do an outer loop over y
         and an inner loop over x, you would get the advantage of
         data locality. *)
      val i : size_t i = g1u2u x + (g1u2u y * record.w)
      macdef pixels = !(record.p)
      val () = pixels[i] := elt

      prval () = fold@ pix
    in
    end

implement {a} {tk}
pixmap_set_at_gint (pix, x, y, elt) =
  pixmap_set_at_guint<a><sizeknd> (pix, g1i2u x, g1i2u y, elt)

implement {a} {tk}
pixmap_get_at_guint {w, h} {x, y} (pix, x, y) =
  case+ pix of
  | @ _pixmap record =>
    let
      prval () = lemma_g1uint_param x
      prval () = lemma_g1uint_param y

      stadef n = w * h
      stadef i = x + (y * w)

      prval () = pixmap_prove_index_bounds {w, h} {x, y} ()
      prval () = prop_verify {0 <= i && i < n} ()

      val i : size_t i = g1u2u x + (g1u2u y * record.w)
      macdef pixels = !(record.p)
      val elt = pixels[i]

      prval () = fold@ pix
    in
      elt
    end

implement {a} {tk}
pixmap_get_at_gint (pix, x, y) =
  pixmap_get_at_guint<a><sizeknd> (pix, g1i2u x, g1i2u y)

implement {a}
pixmap_dump (outf, pix) =
  case+ pix of
  | @ _pixmap record =>
    let
      macdef pixels = !(record.p)
      val n = record.w * record.h
      val success = pixmap$pixels_dump<a> (outf, pixels, n)
      prval () = fold@ pix
    in
      success
    end

implement {a}
pixmap_load (inpf, pix, elt) =
  case+ pix of
  | @ _pixmap record =>
    let
      macdef pixels = !(record.p)
      val n = record.w * record.h
      val success = pixmap$pixels_load<a> (inpf, pixels, n, elt)
      prval () = fold@ pix
    in
      success
    end

(*------------------------------------------------------------------*)

typedef FILEstar = $extype"FILE *"
extern castfn FILEref2star : FILEref -<> FILEstar

implement
pixmap$pixels_dump<rgb24> (outf, pixels, n) =
  let
    val num_written =
      $extfcall (size_t, "fwrite", addr@ pixels, sizeof<rgb24>, n,
                 FILEref2star outf)
  in
    num_written = n
  end

implement
pixmap$pixels_load<rgb24> (inpf, pixels, n, elt) =
  let
    prval [n : int] EQINT () = eqint_make_guint n
    val num_read =
      $extfcall (size_t, "fread", addr@ pixels, sizeof<rgb24>, n,
                 FILEref2star inpf)
  in
    if num_read = n then
      let
        prval () = $UNSAFE.castvwtp2void{@[rgb24][n]} pixels
      in
        true
      end
    else
      begin
        array_initize_elt<rgb24> (pixels, n, elt);
        false
      end
  end

(*------------------------------------------------------------------*)

assume rgb24 = @(uint8, uint8, uint8)

implement {tk}
rgb24_make_uint_uint_uint (r, g, b) =
  let
    (* The prelude tends to miss implementations for type conversions
       to uint8, so let us at least implement conversion from uint to
       uint8. (I do not wish to use a general unsafe cast, because
       that sort of code has caused me bugs before. C does not always
       know how to do a type conversion correctly.) The ats2-xprelude
       package has a much more complete set of implementations
       (generated en masse by m4 macros), but for this task I am
       avoiding such dependencies. *)
    implement
    g0uint2uint<uintknd,uint8knd> i =
      let
        extern castfn g0uint2uint_uint_uint8 : uint -<> uint8
      in
        g0uint2uint_uint_uint8 i
      end
  in
    rgb24_make_tuple @(g0u2u r, g0u2u g, g0u2u b)
  end

implement {tk}
rgb24_make_int_int_int (r, g, b) =
  let
    (* See the comment in rgb24_make_uint_uint_uint. *)
    implement
    g0int2uint<intknd,uint8knd> i =
      let
        extern castfn g0int2uint_int_uint8 : int -<> uint8
      in
        g0int2uint_int_uint8 i
      end
  in
    rgb24_make @(g0i2u r, g0i2u g, g0i2u b)
  end

implement {}
rgb24_make_tuple tup = tup

implement {}
rgb24_values rgb = rgb

(*------------------------------------------------------------------*)

#ifdef BITMAP_TASK_TEST #then

%{^
#include <limits.h>
%}

fn
test_sizeof_rgb24 () : void =
  (* We want to be sure rgb24 takes up exactly 24 bits. Our dump and
     load implementations depend on that. (If it prove not the case on
     some platform, one can write, for that unanticipated platform,
     special implementations of dump and load.) *)
  let
    val- true = sizeof<rgb24> = i2sz 3
    val- true = sizeof<rgb24> * $extval (size_t, "CHAR_BIT") = i2sz 24
  in
  end

fn
test_pixel_load_copy_dump () : void =
  (* Test loading, copying, and dumping of raw 24-bit RGB data from
     SIPI image "Peppers", 4.2.07.tiff:
     https://sipi.usc.edu/database/database.php?volume=misc&image=13#top
     I have the data stored as "4.2.07.raw". *)
  let
    val failure_color = rgb24_make (0xFF, 0x00, 0x00)

    val @(pfgc1 | pix1) = pixmap_make<rgb24> (i2sz 512, i2sz 512)
    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_make<rgb24> (i2sz 512, i2sz 512,
                                              failure_color)
    fun
    copy_pixels {x, y : nat | x <= 512; y <= 512}
                .<512 - x, 512 - y>.
                (pix1 : !pixmap (rgb24, 512, 512),
                 pix2 : !pixmap (rgb24, 512, 512),
                 x    : int x,
                 y    : int y) : void =
      if x = 512 then
        ()
      else if y = 512 then
        copy_pixels (pix1, pix2, succ x, 0)
      else
        begin
          pix2[x, y] := pix1[x, y];
          copy_pixels (pix1, pix2, x, succ y)
        end
    val () = copy_pixels (pix1, pix2, 0, 0)

    val outf = fileref_open_exn ("4.2.07.raw.dumped", file_mode_w)
    val success = dump<rgb24> (outf, pix2)
    val () = fileref_close outf
    val- true = success

    val status = $extfcall (int, "system",
                            "cmp 4.2.07.raw 4.2.07.raw.dumped")
    val- true = status = 0
  in
    free (pfgc1 | pix1);
    free (pfgc2 | pix2)
  end

implement
main0 () =
  begin
    test_sizeof_rgb24 ();
    test_pixel_load_copy_dump ()
  end

#endif

(*------------------------------------------------------------------*)

A test can be run if one has a 786432-byte file and names it 4.2.07.raw. I used the raw data from a commonly used 512x512 test image. You can compile and run the test program thus:

$ patscc -std=gnu2x -g -O2 -DATS_MEMALLOC_LIBC -DATS BITMAP_TASK_TEST bitmap_task.sats bitmap_task.dats
$ ./a.out

You should end up with a copy of the data in a file named 4.2.07.raw.dumped.

AutoHotkey

Works with: AutoHotkey_L
test: 
blue := color(0,0,255)  ; rgb
cyan := color(0,255,255) 
blue_square := Bitmap(10, 10, blue)
cyanppm := Bitmap(10, 10, cyan)
x := blue_square[4,4] ; get pixel(4,4)
msgbox % "blue: 4,4,R,G,B, RGB: " x.R ", " x.G ", " x.B ", " x.rgb()
blue_square[4,4] := cyan ; set pixel(4,4)
x := blue_square[4,4] ; get pixel(4,4)
blue_square.write("blue.ppm")
return
 
Bitmap(width = 1, height = 1, background = 0)
{
global black
black := color(0,0,0)
if !background
background := black
 
    static BitmapType
    if !BitmapType
        BitmapType
        := Object("fill", "Bitmap_Fill"
	         ,"write", "Bitmap_write_ppm3")
 
	img := Object("width", width
                ,"height", height
                , "base"    , BitmapType)
 
	img._SetCapacity(height) ; an array of rows
  img.fill(background)
Return img
}
 
 
Bitmap_Fill(bitmap, color)
{
r := color.r
g := color.g
b := color.b
  loop % bitmap.height
  {
    height := A_Index
    loop % bitmap.width
    {
      width := A_Index
      bitmap[height, width] := color(r, g, b)
    }
  }
 return bitmap
}
 
Bitmap_write_ppm3(bitmap, filename)
{
file := FileOpen(filename, 0x11) ; utf-8, write
file.seek(0,0)
file.write("P3`n" 
. bitmap.width . " " . bitmap.height . "`n"
. "255`n")
  loop % bitmap.height
  {
    height := A_Index
    loop % bitmap.width
    {
      width := A_Index
      color := bitmap[height, width] 
      file.Write(color.R . " ")
      file.Write(color.G . " ")
      file.Write(color.B . " ")
    }
    file.write("`n")
  }
  file.close()
 return 0
}
 
Color(r, g, b)
{
    static ColorType
    if !ColorType
        ColorType
        := Object("rgb"   , "Color_rgb")
 
    return Object("r" , r, "g", g, "b", b
                , "base"    , ColorType)
 
 ; return Object("r" , r, "g", g, "b", b, "rgb", "Color_rgb")
}
 
Color_rgb(clr)
{
return clr.R << 16 | clr.G << 8 | clr.B
}

Axe

All of the functions specified in the task are built in to Axe. Note that bitmaps are always 96x64 black and white. Thus, since each pixel takes 1 bit, a complete bitmap is 768 bytes.

Two bitmaps can be masked together to create 3- and 4-color grayscale.

Buff(768)→Pic1
Fill(Pic1,768,255)
Pxl-Off(45,30,Pic1)

.Display the bitmap to demonstrate
Copy(Pic1)
DispGraph
Pause 4500

Disp pxl-Test(50,50,Pic1)▶Dec,i

BASIC

BASIC256

graphsize 30,30
call fill(rgb(255,0,0))
call setpixel(10,10,rgb(0,255,255))
print "pixel 10,10 is " + pixel(10,10)
print "pixel 20,20 is " + pixel(20,10)

imgsave "BASIC256_bitmap.png"
end

subroutine fill(c)
color c
rect 0,0,graphwidth, graphheight
end subroutine

subroutine setpixel(x,y,c)
color c
plot x,y
end subroutine
Output:
pixel 10,10 is 4278255615
pixel 20,20 is 4294901760

BBC BASIC

BBC BASIC expects a bitmap always to be associated with a window; for simplicity this code uses the main output window.

      Width% = 200
      Height% = 200
      
      REM Set window size:
      VDU 23,22,Width%;Height%;8,16,16,128
      
      REM Fill with an RGB colour:
      PROCfill(100,150,200)
      
      REM Set a pixel:
      PROCsetpixel(100,100,255,255,0)
      
      REM Get a pixel:
      rgb% = FNgetpixel(100,100)
      PRINT RIGHT$("00000" + STR$~rgb%, 6)
      END
      
      DEF PROCfill(r%,g%,b%)
      COLOUR 1,r%,g%,b%
      GCOL 1+128
      CLG
      ENDPROC
      
      DEF PROCsetpixel(x%,y%,r%,g%,b%)
      COLOUR 1,r%,g%,b%
      GCOL 1
      LINE x%*2,y%*2,x%*2,y%*2
      ENDPROC
      
      DEF FNgetpixel(x%,y%)
      LOCAL col%
      col% = TINT(x%*2,y%*2)
      SWAP ?^col%,?(^col%+2)
      = col%

C

Working excerpt from imglib.h usable as "interface" (some includes are needed for other functions of the same category). This code uses functions from category Raster graphics operations. One must create files imglib.h and imglib.c using code from these pages. Start from bitmap page

#ifndef _IMGLIB_0
#define _IMGLIB_0

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <math.h>
#include <sys/queue.h>

typedef unsigned char color_component;
typedef color_component pixel[3];
typedef struct {
    unsigned int width;
    unsigned int height;
    pixel * buf;
} image_t;
typedef image_t * image;

image alloc_img(unsigned int width, unsigned int height);
void free_img(image);
void fill_img(image img,
        color_component r,
        color_component g,
        color_component b );
void put_pixel_unsafe(
       	image img,
        unsigned int x,
        unsigned int y,
        color_component r,
        color_component g,
        color_component b );
void put_pixel_clip(
       	image img,
        unsigned int x,
        unsigned int y,
        color_component r,
        color_component g,
        color_component b );
#define GET_PIXEL(IMG, X, Y) (IMG->buf[ ((Y) * IMG->width + (X)) ])
#endif
image alloc_img(unsigned int width, unsigned int height)
{
    image img;
    img = malloc(sizeof(image_t));
    img->buf = malloc(width * height * sizeof(pixel));
    img->width = width;
    img->height = height;
    return img;
}

void free_img(image img)
{
    free(img->buf);
    free(img);
}

void fill_img(
        image img,
        color_component r,
        color_component g,
        color_component b )
{
    unsigned int i, n;
    n = img->width * img->height;
    for (i=0; i < n; ++i)
    {
        img->buf[i][0] = r;
        img->buf[i][1] = g;
        img->buf[i][2] = b;
    }
}

void put_pixel_unsafe(
       	image img,
        unsigned int x,
        unsigned int y,
        color_component r,
        color_component g,
        color_component b )
{
    unsigned int ofs;
    ofs = (y * img->width) + x;
    img->buf[ofs][0] = r;
    img->buf[ofs][1] = g;
    img->buf[ofs][2] = b;
}

void put_pixel_clip(
       	image img,
        unsigned int x,
        unsigned int y,
        color_component r,
        color_component g,
        color_component b )
{
    if (x < img->width && y < img->height)
      put_pixel_unsafe(img, x, y, r, g, b);
}

C#

This implementation uses a multidemensional array to store the Color structure (which stores the RGB values). No exception catching for out-of-bounds errors if they occur, but provides Height and Width properties so a program using it can avoid them.

public class Bitmap
{
    public struct Color
    {
        public byte Red { get; set; }
        public byte Blue { get; set; }
        public byte Green { get; set; }
    }
    Color[,] _imagemap;
    public int Width { get { return _imagemap.GetLength(0); } }
    public int Height { get { return _imagemap.GetLength(1); } }
    public Bitmap(int width, int height)
    {
        _imagemap = new Color[width, height];
    }
    public void Fill(Color color)
    {
        for (int y = 0; y < Height; y++)
            for (int x = 0; x < Width; x++)
            {
                _imagemap[x, y] = color;
            }
    }
    public Color GetPixel(int x, int y)
    {
        return _imagemap[x, y];
    }
    public void SetPixel(int x, int y, Color color)
    {
        _imagemap[x, y] = color;
    }
}

C++

Works with: C++98
Library: boost
#include <iostream>
#include <boost/gil/gil_all.hpp>
int main()
{
    using namespace boost::gil;
    // create 30x40 image
    rgb8_image_t img(30, 40);

    // fill with red
    rgb8_pixel_t red(255, 0, 0);
    fill_pixels(view(img), red);

    // set pixel at 10x20 to blue
    rgb8_pixel_t blue(0, 0, 255);
    view(img)(10, 20) = blue;

    // read the value of pixel at 11x20
    rgb8_pixel_t px = const_view(img)(11, 20);
    std::cout << "the pixel at 11, 20 is " << (unsigned)px[0] << ':' << (unsigned)px[1] << ':' << (unsigned)px[2]  << '\n';
}

See also Basic bitmap storage/C++

Clojure

(import '[java.awt Color Graphics Image]
	'[java.awt.image BufferedImage])

(defn blank-bitmap [width height]
  (BufferedImage. width height BufferedImage/TYPE_3BYTE_BGR))

(defn fill [image color]
  (doto (.getGraphics image)
    (.setColor color)
    (.fillRect 0 0 (.getWidth image) (.getHeight image))))

(defn set-pixel [image x y color]
  (.setRGB image x y (.getRGB color)))

(defn get-pixel [image x y]
  (Color. (.getRGB image x y)))

Common Lisp

(defpackage #:rgb-pixel-buffer
  (:use #:common-lisp)
  (:export #:rgb-pixel-component #:rgb-pixel #:rgb-pixel-buffer
           #:+red+ #:+green+ #:+blue+ #:+black+ #:+white+
           #:make-rgb-pixel #:make-rgb-pixel-buffer #:rgb-pixel-buffer-width
           #:rgb-pixel-buffer-height #:rgb-pixel-red #:rgb-pixel-green
           #:rgb-pixel-blue #:fill-rgb-pixel-buffer))
(in-package #:rgb-pixel-buffer)

(deftype rgb-pixel-component ()
  '(unsigned-byte 8))

(deftype rgb-pixel ()
  '(unsigned-byte 24))

(deftype rgb-pixel-buffer (&optional (width '*) (height '*))
  `(array rgb-pixel (,width ,height)))

(defconstant +black+ 0)
(defconstant +white+ #xFFFFFF)
(defconstant +red+ #xFF0000)
(defconstant +green+ #x00FF00)
(defconstant +blue+ #x0000FF)

(defun make-rgb-pixel (r g b)
  (declare (type rgb-pixel-component r g b))
  (logior (ash r 16) (ash g 8) b))

(defun rgb-pixel-red (rgb)
  (declare (type rgb-pixel rgb))
  (logand (ash rgb -16) #xFF))

(defun rgb-pixel-green (rgb)
  (declare (type rgb-pixel rgb))
  (logand (ash rgb -8) #xFF))

(defun rgb-pixel-blue (rgb)
  (declare (type rgb-pixel rgb))
  (logand rgb #xFF))

(defun make-rgb-pixel-buffer (width height &optional (initial-element +black+))
  (declare (type (integer 1) width height))
  (declare (type rgb-pixel initial-element))
  (make-array (list width height) 
    :element-type 'rgb-pixel 
    :initial-element initial-element))

(defun rgb-pixel-buffer-width (buffer)
  (first (array-dimensions buffer)))

(defun rgb-pixel-buffer-height (buffer)
  (second (array-dimensions buffer)))

(defun rgb-pixel (buffer x y)
  (declare (type rgb-pixel-buffer buffer))
  (declare (type (integer 0) x y))
  (aref buffer x y))

(defun (setf rgb-pixel) (value buffer x y)
  (declare (type rgb-pixel-buffer buffer))
  (declare (type rgb-pixel value))
  (declare (type (integer 0) x y))
  (setf (aref buffer x y) value))

(defun fill-rgb-pixel-buffer (buffer pixel)
  (declare (type rgb-pixel-buffer buffer))
  (declare (type rgb-pixel pixel))
  (let* ((dimensions (array-dimensions buffer))
	 (width (first dimensions))
	 (height (second dimensions)))
    (loop 
       :for y :of-type fixnum :upfrom 0 :below height
       :do (loop 
	      :for x :of-type fixnum :upfrom 0 :below width
	      :do (setf (rgb-pixel buffer x y) pixel)))
    buffer))

Example:

(defvar *buffer* (make-rgb-pixel-buffer 10 10))
(fill-rgb-pixel-buffer *buffer* +white+)
(setf (rgb-pixel *buffer* 0 0) +red+)
(setf (rgb-pixel *buffer* 0 9) +red+)
(setf (rgb-pixel *buffer* 9 0) +red+)
(setf (rgb-pixel *buffer* 9 9) +red+)

Crystal

class RGBColor
  getter red, green, blue

  def initialize(@red = 0_u8, @green = 0_u8, @blue = 0_u8)
  end
 
  RED   = new(red: 255_u8)
  GREEN = new(green: 255_u8)
  BLUE  = new(blue: 255_u8)
  BLACK = new
  WHITE = new(255_u8, 255_u8, 255_u8)
end

class Pixmap
  getter width, height
  @data : Array(Array(RGBColor))

  def initialize(@width : Int32, @height : Int32)
    @data = Array.new(@width) { Array.new(@height, RGBColor::WHITE) }
  end

  def fill(color)
    @data.each &.fill(color)
  end

  def [](x, y)
    @data[x][y]
  end

  def []=(x, y, color)
    @data[x][y] = color
  end
end

bmap = Pixmap.new(5, 5)
pp bmap

D

This code is a little complex because many Tasks use this module for various purposes.

module bitmap;

import std.stdio, std.array, std.exception, std.string, std.conv,
       std.algorithm, std.ascii;

final class Image(T) {
    static if (is(typeof({ auto x = T.black; })))
        const static T black = T.black;
    else
        const static T black = T.init;
    static if (is(typeof({ auto x = T.white; })))
        const static T white = T.white;

    T[] image;
    private size_t nx_, ny_;

    this(in int nxx=0, in int nyy=0, in bool inizialize=true)
    pure nothrow {
        allocate(nxx, nyy, inizialize);
    }

    void allocate(in int nxx=0, in int nyy=0, in bool inizialize=true)
    pure nothrow @safe in {
        assert(nxx >= 0 && nyy >= 0);
    } body {
        this.nx_ = nxx;
        this.ny_ = nyy;
        if (nxx * nyy > 0) {
            if (inizialize)
                image.length = nxx * nyy;
            else // Optimization.
                image = minimallyInitializedArray!(typeof(image))
                                                  (nxx * nyy);
        }
    }

    @property Image dup() const pure nothrow @safe {
        auto result = new Image();
        result.image = this.image.dup;
        result.nx_ = this.nx;
        result.ny_ = this.ny;
        return result;
    }

    static Image fromData(T[] data, in size_t nxx=0, in size_t nyy=0)
    pure nothrow @safe in {
        assert(nxx >= 0 && nyy >= 0 && data.length == nxx * nyy);
    } body {
        auto result = new Image();
        result.image = data;
        result.nx_ = nxx;
        result.ny_ = nyy;
        return result;
    }

    @property size_t nx() const pure nothrow @safe @nogc { return nx_; }
    @property size_t ny() const pure nothrow @safe @nogc { return ny_; }

    ref T opIndex(in size_t x, in size_t y) pure nothrow @safe @nogc
    in {
        assert(x < nx_ && y < ny_);
        //assert(x < nx_, format("opIndex, x=%d, nx=%d", x, nx));
        //assert(y < ny_, format("opIndex, y=%d, ny=%d", y, ny));
    } body {
        return image[x + y * nx_];
    }

    T opIndex(in size_t x, in size_t y) const pure nothrow @safe @nogc
    in {
        assert(x < nx_ && y < ny_);
        //assert(x < nx_, format("opIndex, x=%d, nx=%d", x, nx));
        //assert(y < ny_, format("opIndex, y=%d, ny=%d", y, ny));
    } body {
        return image[x + y * nx_];
    }

    T opIndexAssign(in T color, in size_t x, in size_t y)
    pure nothrow @safe @nogc
    in {
        assert(x < nx_ && y < ny_);
        //assert(x < nx_, format("opIndex, x=%d, nx=%d", x, nx));
        //assert(y < ny_, format("opIndex, y=%d, ny=%d", y, ny));
    } body {
        return image[x + y * nx_] = color;
    }

    void opIndexUnary(string op)(in size_t x, in size_t y)
    pure nothrow @safe @nogc
    if (op == "++" || op == "--") in {
        assert(x < nx_ && y < ny_);
    } body {
        mixin("image[x + y * nx_] " ~ op ~ ";");
    }

    void clear(in T color=this.black) pure nothrow @safe @nogc {
        image[] = color;
    }

    /// Convert a 2D array of chars to a binary Image.
    static Image fromText(in string txt,
                          in char one='#', in char zero='.') pure {
        auto M = txt
                 .strip
                 .split
                 .map!(row => row
                              .filter!(c => c == one || c == zero)
                              .map!(c => T(c == one))
                              .array)
                 .array;
        assert(M.join.length > 0); // Not empty.
        foreach (row; M)
            assert(row.length == M[0].length); // Rectangular
        return Image.fromData(M.join, M[0].length, M.length);
    }

    /// The axis origin is at the top left.
    void textualShow(in char bl='#', in char wh='.') const nothrow {
        size_t i = 0;
        foreach (immutable y; 0 .. ny_) {
            foreach (immutable x; 0 .. nx_)
                putchar(image[i++] == black ? bl : wh);
            putchar('\n');
        }
    }
}


struct RGB {
    ubyte r, g, b;
    static immutable black = typeof(this)();
    static immutable white = typeof(this)(255, 255, 255);
}


Image!RGB loadPPM6(ref Image!RGB img, in string fileName) {
    if (img is null)
        img = new Image!RGB;
    auto f = File(fileName, "rb");
    enforce(f.readln.strip == "P6");
    string line;
    do {
        line = f.readln();
    } while (line.length && line[0] == '#'); // Skip comments.
    const size = line.split;
    enforce(size.length == 2);
    img.allocate(size[0].to!uint, size[1].to!uint);
    enforce(f.readln().strip() == "255");
    auto l = new ubyte[img.nx * 3];
    size_t i = 0;
    foreach (immutable y; 0 .. img.ny) {
        f.rawRead!ubyte(l);
        foreach (immutable x; 0 .. img.nx)
            img.image[i++] = RGB(l[x * 3], l[x * 3 + 1], l[x * 3 + 2]);
    }
    return img;
}


void savePPM6(in Image!RGB img, in string fileName)
in {
    assert(img !is null);
    assert(img.nx > 0 && img.nx > 0);
} body {
    auto f = File(fileName, "wb");
    f.writefln("P6\n%d %d\n255", img.nx, img.ny);
    size_t i = 0;
    foreach (immutable y; 0 .. img.ny)
        foreach (immutable x; 0 .. img.nx) {
            immutable p = img.image[i++];
            f.write(cast(char)p.r, cast(char)p.g, cast(char)p.b);
        }
}

version (bitmap_main) {
    void main() {
        auto img = new Image!RGB(30, 10);
        img[4, 5] = RGB.white;
        img.textualShow;
    }
}

Compiling it with version=bitmap_main prints:

Output:
##############################
##############################
##############################
##############################
##############################
####.#########################
##############################
##############################
##############################
##############################

Delphi

program BitmapTest;

{$APPTYPE CONSOLE}

type
  TColor = record
  private
    function GetColor: Cardinal;
    procedure SetColor(const Value: Cardinal);
  public
    Red, Green, Blue, Alpha: Byte;
    property Color: Cardinal read GetColor write SetColor;
  end;

  TBitmap = class
  private
    FPixels: array of array of TColor;
    FHeight: Integer;
    FWidth: Integer;
    function GetPixel(X, Y: integer): TColor;
  public
    procedure Fill(aColor: TColor); overload;
    procedure Fill(aColor: Cardinal); overload;
    procedure SetSize(w, h: Integer);
    constructor Create(); overload;
    constructor Create(w, h: Integer); overload;
    property Height: Integer read FHeight;
    property Width: Integer read FWidth;
    property Pixel[X, Y: integer]: TColor read GetPixel;
  end;

{ TColor }

function TColor.GetColor: Cardinal;
begin
  Result := (alpha shl 24) + (red shl 16) + (green shl 8) + blue;
end;

procedure TColor.SetColor(const Value: Cardinal);
begin
  blue := (Value and $FF);
  green := ((Value shr 8) and $FF);
  red := ((Value shr 16) and $FF);
  alpha := ((Value shr 24) and $FF);
end;

{ TBitmap }

constructor TBitmap.Create;
begin
  inherited;
  FHeight := 0;
  FWidth := 0;
end;

constructor TBitmap.Create(w, h: Integer);
begin
  Create;
  SetSize(w, h);
end;

procedure TBitmap.Fill(aColor: Cardinal);
var
  x, y: Integer;
begin
  if (Width > 0) and (Height > 0) then
    for x := 0 to width - 1 do
      for y := 0 to height - 1 do
        FPixels[x, y].Color := aColor;
end;

procedure TBitmap.Fill(aColor: TColor);
begin
  Fill(aColor.Color);
end;

function TBitmap.GetPixel(X, Y: integer): TColor;
begin
  Result := FPixels[X, Y];
end;

procedure TBitmap.SetSize(w, h: Integer);
var
  i: Integer;
begin
  if (h = 0) or (w = 0) then
  begin
    h := 0;
    w := 0;
  end;

  FHeight := h;
  FWidth := w;
  SetLength(FPixels, w);
  if w > 0 then
    for i := 0 to w - 1 do
      SetLength(FPixels[i], h);
end;

var
  bmp: TBitmap;
  x, y: Integer;

begin
  bmp := TBitmap.Create(200, 200);
  bmp.Fill($00FF0000);
  for y := 0 to bmp.Height - 1 do
    for x := 0 to bmp.Width - 1 do
    begin
      if x mod 2 = 1 then
        bmp.Pixel[x, y].Color := $0000FF;
    end;
  bmp.Free;
end.


Delphi

Works with: Delphi version 6.0

This is a pure Delphi example using standard Delphi controls and libraries that already have raster and bitmap objects and operations built in.

Bascially, Delphi has a powerful set of tools for manipulating graphic objects. All graphic objects including Screens, Printers, Windows or Bitmaps, have a property called a "Canvas." As a consequence, the same code can draw on the Screen, the Printer, a Window or a Bitmap. A Canvas has powerful function that allow you to draw pixels, lines, rectangles, circles, elispes, polygons and text on any graphic object. The code below demonstrates many of the function available in a canvas.

procedure ShowBitmapFunctions(Image: TImage);
{Code to demonstrate some of the main features the Delphi "TCanvas" object}
var I,X,Y: integer;
var C: TColor;
begin
{Draw red rectangle with 3 pixels wide lines}
Image.Canvas.Pen.Color:=clRed;
Image.Canvas.Pen.Width:=3;
Image.Canvas.Rectangle(50,50,500,300);
{Flood fill rectangle blue}
Image.Canvas.Brush.Color:=clBlue;
Image.Canvas.FloodFill(55,55,clRed,fsBorder);
{Draw random dots on the screen}
for I:=1 to 1000 do
	begin
	X:=trunc((Random * 450) + 50);
	Y:=trunc((Random * 250) + 50);
	C:=RGB(Random(255),Random(255),Random(255));
	{draw 9 pixels for each point to make dots more visible}
	Image.Canvas.Pixels[X-1,Y-1]:=C;
	Image.Canvas.Pixels[X  ,Y-1]:=C;
	Image.Canvas.Pixels[X+1,Y-1]:=C;
	Image.Canvas.Pixels[X-1,Y  ]:=C;
	Image.Canvas.Pixels[X  ,Y  ]:=C;
	Image.Canvas.Pixels[X+1,Y  ]:=C;
	Image.Canvas.Pixels[X-1,Y+1]:=C;
	Image.Canvas.Pixels[X  ,Y+1]:=C;
	Image.Canvas.Pixels[X+1,Y+1]:=C;
	end;
{Draw lime-green line from corner to cornder}
Image.Canvas.Pen.Color:=clLime;
Image.Canvas.MoveTo(50,50);
Image.Canvas.LineTo(500,300);
{Sample pixel color at 51,51}
C:=Image.Canvas.Pixels[51,51];
{Display the color value }
Image.Canvas.Brush.Color:=clAqua;
Image.Canvas.Font.Size:=25;
Image.Canvas.Font.Color:=clRed;
Image.Canvas.TextOut(5,5,IntToHex(C,8));
{Tell Delphi to update the Window}
Image.Repaint;
end;
Output:

Elapsed Time: 39.038 ms.

E

This example includes the write ppm file code, because it is most naturally written as a method on the image object.

def makeFlexList := <elib:tables.makeFlexList>
def format := <import:java.lang.makeString>.format

def CHANNELS := 3
def UByte := 0..255

def makeColor {
  to fromFloat(r, g, b) {
    return makeColor.fromByte((r * 255).round(),
                              (g * 255).round(),
                              (b * 255).round())
  }
  to fromByte(r :UByte, g :UByte, b :UByte) {
    def color {
      to __printOn(out) {
        out.print(format("%02x%02x%02x", [color.rb(), color.gb(), color.bb()]))
      }
      to rf() { return r / 255 }
      to gf() { return g / 255 }
      to bf() { return b / 255 }
      to rb() { return r }
      to gb() { return g }
      to bb() { return b }
    }
    return color
  }
}

/** Convert 0..255 into 0..127 -128..-1 */
def sign(v) {
  return v %% 256 - 2*(v & 128)
}

def makeImage(width, height) {
  # NOTE: The primary E implementation is in Java and Java's fixed-size integers only 
  # come in signed varieties. Therefore, there is a little bit of extra arithmetic.
  #
  # In an ideal E implementation we would specify the type 0..255, but this is not
  # currently possible everywhere, or efficient.
  
  def storage := makeFlexList.fromType(<type:java.lang.Byte>, width * height * CHANNELS)
  storage.setSize(width * height * CHANNELS)

  def X := 0..!width
  def Y := 0..!height

  def flexImage {
    to __printOn(out) {
      for y in Y {
        out.print("[")
        for x in X {
          out.print(flexImage[x, y], " ")
        }
        out.println("]")
      }
    }
    to width() { return width }
    to height() { return height }
    to fill(color) {
      for x in X {
        for y in Y {
          flexImage[x, y] := color
        }
      }
    }
    to get(x :X, y :Y) {
      def base := (y * width + x) * CHANNELS
      return makeColor.fromByte(storage[base + 0] %% 256,
                                storage[base + 1] %% 256,
                                storage[base + 2] %% 256)
    }
    /** Provided to make [[Flood fill]] slightly less insanely slow. */
    to test(x :X, y :Y, c) {
      def base := (y * width + x) * CHANNELS
      return storage[base + 0] <=> sign(c.rb()) &&
             storage[base + 1] <=> sign(c.gb()) &&
             storage[base + 2] <=> sign(c.bb())
    }
    to put(x :X, y :Y, c) { 
      def base := (y * width + x) * CHANNELS
      storage[base + 0] := sign(c.rb())
      storage[base + 1] := sign(c.gb())
      storage[base + 2] := sign(c.bb())
    }
    to writePPM(outputStream) {
      outputStream.write(`P6$\n$width $height$\n255$\n`.getBytes("US-ASCII"))
      outputStream.write(storage.getArray())
    }
    /** Used for [[Read ppm file]] */
    to replace(list :List) {
      require(list.size() == width * height * CHANNELS)
      storage(0) := list
    }
  }
  
  return flexImage
}

Examples/tests:

? def i := makeImage(3, 3)
# value: [000000 000000 000000 ]
#        [000000 000000 000000 ]
#        [000000 000000 000000 ]
#        

? i.fill(makeColor.fromFloat(1, 0, 0))
? i
# value: [ff0000 ff0000 ff0000 ]
#        [ff0000 ff0000 ff0000 ]
#        [ff0000 ff0000 ff0000 ]
#        

? i[1, 1] := makeColor.fromFloat(0.5, 0.5, 0.5)
# value: 808080

? i
# value: [ff0000 ff0000 ff0000 ]
#        [ff0000 808080 ff0000 ]
#        [ff0000 ff0000 ff0000 ]
#        

? i[0, 1]
# value: ff0000

? i[1, 1]
# value: 808080

? i.writePPM(<import:java.io.makeFileOutputStream>(<file:~/Desktop/Rosetta.ppm>))

EchoLisp

(lib 'plot)
(define width 600)
(define height 400)

(plot-size width height) ;; set image size

(define (blue x y) (rgb 0.0 0.0 1.0)) ;; a constant function
(plot-rgb blue 1 1) ;; blue everywhere

(lib 'types) ;; uint32 and uint8 vector types

;; bit-map pixel access
(define bitmap (pixels->uint32-vector)) ;; screen to vector of int32
     240000

(define (pix-at x y) (vector-ref bitmap (+ x (* y width))))
(rgb->list (pix-at 100 200))  (0 0 255 255)  ;; rgb blue

;; writing to bitmap
(define (set-color-xy x y col) (vector-set! bitmap (+ x (* y width)) col))

(for* ((x 100)(y 200)) (set-color-xy x y (rgb 1 1 0))) ;; to bitmap
(vector->pixels bitmap) ;; bitmap to screen


;; bit-map color components (r g b a) = index (0 1 2 3) access
(define bitmap (pixels->uint8-clamped-vector)) ;; screen to vector of uint8
(vector-length bitmap)
     960000
(define (blue-at-xy x y) (vector-ref bitmap (+ x 3 (* y width)))) ;; 3 = blue component
(blue-at-xy 100 200)
     255

Elixir

Translation of the erlang version of the code.

defmodule RosBitmap do
  defrecord Bitmap, pixels: nil, shape: {0, 0}

  defp new(width, height, {:rgb, r, g, b}) do
    Bitmap[
      pixels: :array.new(width * height,
        {:default, <<r::size(8), g::size(8), b::size(8)>>}),
      shape: {width, height}]
  end

  def new(width, height), do: new(width, height, {:rgb, 0, 0, 0})

  def fill(Bitmap[shape: {width, height}], {:rgb, _r, _g, _b}=color) do
    new(width, height, color)
  end

  def set_pixel(Bitmap[pixels: pixels, shape: {width, _height}]=bitmap,
      {:at, x, y}, {:rgb, r, g, b}) do
    index = x + y * width
    bitmap.pixels(:array.set(index, <<r::size(8), g::size(8), b::size(8)>>, pixels))
  end

  def get_pixel(Bitmap[pixels: pixels, shape: {width, _height}], {:at, x, y}) do
    index = x + y * width
    <<r::size(8), g::size(8), b::size(8)>> = :array.get(index, pixels)
    {:rgb, r, g, b}
  end
end

Erlang

Stores pixels as a 1d array and colors as binaries.

-module(ros_bitmap).

-export([new/2, fill/2, set_pixel/3, get_pixel/2]).

-record(bitmap, {
    pixels = nil,
    shape = {0, 0}
  }).

new(Width, Height) ->
  #bitmap{pixels=array:new(Width * Height, {default, <<0:8, 0:8, 0:8>>}), shape={Width, Height}}.

fill(#bitmap{shape={Width, Height}}, {rgb, R, G, B}) ->
  #bitmap{
    pixels=array:new(Width * Height, {default, <<R:8, G:8, B:8>>}),
    shape={Width, Height}}.

set_pixel(#bitmap{pixels=Pixels, shape={Width, _Height}}=Bitmap, {at, X, Y}, {rgb, R, G, B}) ->
  Index = X + Y * Width,
  Bitmap#bitmap{pixels=array:set(Index, <<R:8, G:8, B:8>>, Pixels)}.

get_pixel(#bitmap{pixels=Pixels, shape={Width, _Height}}, {at, X, Y}) ->
  Index = X + Y * Width,
  <<R:8, G:8, B:8>> = array:get(Index, Pixels),
  {rgb, R, G, B}.

Euphoria

-- Some color constants:
constant
    black = #000000,
    white = #FFFFFF,
    red =   #FF0000,
    green = #00FF00,
    blue =  #0000FF

-- Create new image filled with some color
function new_image(integer width, integer height, atom fill_color)
    return repeat(repeat(fill_color,height),width)
end function

-- Usage example:
sequence image
image = new_image(800,600,black)

-- Set pixel color:
image[400][300] = red

-- Get pixel color
atom color
color = image[400][300] -- Now color is #FF0000

?color -- Should print out 16711680

F#

FSharp can accomplish this task in several ways. This version is purely functional. The bitmap data structure does not mutate. Set pixel, for example, simply transforms the input bitmap into a new bitmap with that pixel set to the input color. If you have Framework 4.5, you can use ImmutableArray to force this immutability.

Solution:

//pure functional version ... changing a pixel color provides a new Bitmap
type Color = {red: byte; green: byte; blue: byte}
type Point = {x:uint32; y:uint32}
type Bitmap = {color: Color array; maxX: uint32; maxY: uint32} 

let colorBlack = {red = (byte) 0; green = (byte) 0; blue = (byte) 0}
let emptyBitmap = {color = Array.empty; maxX = (uint32) 0; maxY = (uint32) 0}
let bitmap (width: uint32) (height: uint32) = 
    match width, height with
    | 0u,0u | 0u,_ | _, 0u -> emptyBitmap
    | _,_ -> {color = Array.create ((int) (width * height)) colorBlack; 
            maxX = width; 
            maxY = height}
let getPixel point bitmap =
    match bitmap.color with
    | c when c |> Array.isEmpty -> None 
    | c when (uint32) c.Length <= (point.y * bitmap.maxY + point.x) -> None
    | c -> Some c.[(int) (point.y * bitmap.maxY + point.x)]
let setPixel point color bitmap =
    {bitmap with color = bitmap.color |> Array.mapi (function 
                | i when i = (int) (point.y * bitmap.maxY + point.x) -> 
                    (fun _ -> color) 
                | _ -> id)}    
let fill color bitmap = {bitmap with color = bitmap.color |> Array.map (fun _ ->color)}

Tests:

//setups
//==check pixel for color function
let check bitmap color (x,y) = 
    match (getPixel {x=x;y=y} bitmap) with 
    | Some(v) -> v = color 
    | _ -> false
let allPixels i j = [for x in [0u..(i-1u)] do for y in [0u..(j-1u)] -> (x,y)]

//create new empty bitmap
let myBitmap = bitmap 0u 0u
printfn "Is empty: %b" (myBitmap = emptyBitmap)
let myBitmap2 = bitmap 1u 0u
printfn "Is empty: %b" (myBitmap2 = emptyBitmap)
let myBitmap3 = bitmap 0u 1u
printfn "Is empty: %b" (myBitmap3 = emptyBitmap)    
//create normal bitmap
let myBitmap4 = bitmap 14u 14u
printfn "Is not empty: %b" (not (myBitmap4 = emptyBitmap))    
//just check one color
printfn "Is 1,1 black: %b" (check myBitmap4 colorBlack (1u,1u))
//check out of range color
printfn "Is 100,100 nothing: %b" (not(check myBitmap4 colorBlack (100u,100u)))
//make sure all pixels are black
printfn "Is all black: %b" ((allPixels 14u 14u) |> List.forall (check myBitmap4 colorBlack)) 
//fill bitmap color
let colorWhite = {red = (byte) 255; green = (byte) 255; blue = (byte) 255}
let myBitmap5 = myBitmap4 |> fill colorWhite
printfn "Is all white: %b" ((allPixels 14u 14u) |> List.forall (check myBitmap5 colorWhite)) 
//change just one pixel
let myBitmap6 = myBitmap5 |> setPixel {x=5u;y=10u} colorBlack
printfn "Is 5,10 black: %b" (check myBitmap4 colorBlack (5u,10u))
Output:

Is empty

true

Is empty: true

Is empty: true

Is not empty: true

Is 1,1 black: true

Is 100,100 nothing: true

Is all black: true

Is all white: true

Is 5,10 black: true Usage:

bitmap 14u 14u
|> fill {red = (byte) 200; green = (byte) 0; blue = (byte) 10}
|> setPixel {x=5u;y=10u} {red = (byte) 0; green = (byte) 0; blue = (byte) 0}
|> getPixel {x=5u;y=10u}
|> printfn "%A"
Output:

Some {red = 0uy;

     green = 0uy;
     blue = 0uy;}

Factor

The image is a matrix of triples {R,G,B}. The various utilities could be defined in another file, most of them are not used right now, but we need them for drawing so I put every thing here..

USING: arrays fry kernel math.matrices sequences ;
IN: rosettacode.raster.storage

! Various utilities
: meach ( matrix quot -- ) [ each ] curry each ; inline
: meach-index ( matrix quot -- ) 
    [ swap 2array ] prepose
    [ curry each-index ] curry each-index ; inline
: mmap ( matrix quot -- matrix' ) [ map ] curry map ; inline
: mmap! ( matrix quot -- matrix' ) [ map! ] curry map! ; inline
: mmap-index ( matrix quot -- matrix' ) 
    [ swap 2array ] prepose
    [ curry map-index ] curry map-index ; inline

: matrix-dim ( matrix -- i j ) [ length ] [ first length ] bi ;
: set-Mi,j ( elt {i,j} matrix -- ) [ first2 swap ] dip nth set-nth ;
: Mi,j ( {i,j} matrix -- elt ) [ first2 swap ] dip nth nth ;

! The storage functions
: <raster-image> ( width height -- image ) 
    zero-matrix [ drop { 0 0 0 } ] mmap ;
: fill-image ( {R,G,B} image -- image ) 
    swap '[ drop _ ] mmap! ;
: set-pixel ( {R,G,B} {i,j} image -- ) set-Mi,j ; inline
: get-pixel ( {i,j} image -- pixel ) Mi,j ; inline

FBSL

Volatility in FBSL is a feature uncommon to most other languages. It is the ability of its intrinsic functions as well as its user-defined functions, DynAsm and DynC blocks, and functions imported from 3rd-party DLL's to preserve their return values between function calls in FBSL Variants that have the same names as their respective functions but use neither the parentheses nor the arguments. These Variants belong to the global namespace and can be used throughout the entire script until another fully qualified function call to their respective functions is made, whereby they change their values accordingly. The feature minimizes the need for temporary variables and assignments.

This feature is a logical extension of VisualBasic way to formalize its function return value by assigning it to a Variant of the same name as that of the respective function. However, the VB Variant is only effective within the scope of its own function.

Using pure FBSL's built-in graphics functions:

#DEFINE WM_LBUTTONDOWN 513
#DEFINE WM_RBUTTONDOWN 516
#DEFINE WM_CLOSE 16

FBSLSETFORMCOLOR(ME, RGB(0, 255, 255)) ' Cyan: set persistent background color
DRAWWIDTH(5) ' Adjust point size
FBSL.GETDC(ME) ' Use volatile FBSL.GETDC below to avoid extra assignments

RESIZE(ME, 0, 0, 300, 200)
CENTER(ME)
SHOW(ME)

BEGIN EVENTS
	SELECT CASE CBMSG
		CASE WM_LBUTTONDOWN ' Set color at current coords as hex literal
			PSET(FBSL.GETDC, LOWORD(CBLPARAM), HIWORD(CBLPARAM), &H0000FF) ' Red: Windows stores colors in BGR order
		CASE WM_RBUTTONDOWN ' Get color at current coords as hex literal
			FBSLSETTEXT(ME, "&H" & HEX(POINT(FBSL.GETDC, LOWORD(CBLPARAM), HIWORD(CBLPARAM))))
		CASE WM_CLOSE ' Clean up
			FBSL.RELEASEDC(ME, FBSL.GETDC)
	END SELECT
END EVENTS
Output:

Forth

This creates bitmaps on the heap (they may be deallocated with "FREE"). 32-bit or greater cells are assumed, one pixel per cell. This automatically word-aligns rows, so a separate stride field is not required.

hex
0000ff constant red
00ff00 constant green
ff0000 constant blue
decimal

1 cells constant pixel
: pixels cells ;

: bdim ( bmp -- w h ) 2@ ;
: bheight ( bmp -- h ) @ ;
: bwidth ( bmp -- w ) bdim drop ;
: bdata ( bmp -- addr ) 2 cells + ;

: bitmap ( w h -- bmp )
  2dup * pixels bdata allocate throw
  dup >r 2! r> ;

: bfill ( pixel bmp -- )
  dup bdata swap bdim * pixels
  bounds do
    dup i !
  pixel +loop
  drop ;

: bxy ( x y bmp -- addr )
  dup >r bwidth * + pixels r> bdata + ;

: b@ ( x y bmp -- pixel ) bxy @ ;
: b! ( pixel x y bmp -- ) bxy ! ;

: bshow ( bmp -- )
  hex
  dup bdim
  0 do cr
    dup 0 do
      over i j rot b@ if [char] * else bl then emit  \ 7 u.r
    loop
  loop
  2drop decimal ;

4 3 bitmap value test
red test bfill
test bshow cr

Fortran

See Basic bitmap storage/Fortran

FreeBASIC

Screenres 320, 240, 8
Dim Shared As Integer w, h
Screeninfo w, h
Const As Ubyte cyan    = 3
Const As Ubyte red     = 4

Sub rellenar(c As Integer)
    Line (0,0) - (w/3, h/3), red, BF
End Sub

Sub establecePixel(x As Integer, y As Integer, c As Integer)
    Pset (x,y), cyan
End Sub

rellenar(12)
establecePixel(10,10, cyan)
Locate 12
Print "pixel 10,10 es " & Point(10,10)
Print "pixel 20,20 es " & Point(20,10)

Bsave "FreeBASIC_bitmap.bmp", 0
Sleep

Go

Standard library

Go's standard library include image, color, and drawing packages and the source for them is easy to read. There is also a Go Blog article on the image package The image.NRGBA type supports everything this task requires (the 'A' is for alpha channel, each are 8 bits, if 16 bits each of RGBA is desired there is also the image.NRGBA64 type). The 'N' of NRGBA stands for Non-alpha-premultiplied, color values can trivially be converted to/from alpha-premultiplied RGBA values via a color.Model.

Here's how to use the standard packages to do what this task requires:

package main

import (
	"bytes"
	"fmt"
	"image"
	"image/color"
	"image/draw"
	"image/png"
)

func main() {
	// A rectangle from 0,0 to 300,240.
	r := image.Rect(0, 0, 300, 240)

	// Create an image
	im := image.NewNRGBA(r)

	// set some color variables for convience
	var (
		red  = color.RGBA{0xff, 0x00, 0x00, 0xff}
		blue = color.RGBA{0x00, 0x00, 0xff, 0xff}
	)

	// Fill with a uniform color
	draw.Draw(im, r, &image.Uniform{red}, image.ZP, draw.Src)

	// Set individual pixels
	im.Set(10, 20, blue)
	im.Set(20, 30, color.Black)
	im.Set(30, 40, color.RGBA{0x10, 0x20, 0x30, 0xff})

	// Get the values of specific pixels as color.Color types.
	// The color will be in the color.Model of the image (in this
	// case color.NRGBA) but color models can convert their values
	// to other models.
	c1 := im.At(0, 0)
	c2 := im.At(10, 20)

	// or directly as RGB components (scaled values)
	redc, greenc, bluec, _ := c1.RGBA()
	redc, greenc, bluec, _ = im.At(30, 40).RGBA()

	// Images can be read and writen in various formats
	var buf bytes.Buffer
	err := png.Encode(&buf, im)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println("Image size:", im.Bounds().Dx(), "×", im.Bounds().Dy())
	fmt.Println(buf.Len(), "bytes when encoded as PNG.")
	fmt.Printf("Pixel at %7v is %v\n", image.Pt(0, 0), c1)
	fmt.Printf("Pixel at %7v is %#v\n", image.Pt(10, 20), c2) // %#v shows type details
	fmt.Printf("Pixel at %7v has R=%d, G=%d, B=%d\n",
		image.Pt(30, 40), redc, greenc, bluec)
}
Output:
Image size: 300 × 240
786 bytes when encoded as PNG.
Pixel at   (0,0) is {255 0 0 255}
Pixel at (10,20) is color.NRGBA{R:0x0, G:0x0, B:0xff, A:0xff}
Pixel at (30,40) has R=4112, G=8224, B=12336

DIY

Not a complete working program. Presented here are just types and functions requested by the task.

// Raster package used with a number of RC tasks.
//
// For each task, documentation in package main source will list this
// file and others that are necessary to build a raster package with
// sufficient functionality for the task.  To build a working program,
// build a raster package from the files listed, install the package,
// and then compile and link the package main that completes the task.
//
// Alternatively, files in the raster package can be combined as desired
// to build a package that meets the needs of multiple tasks.
package raster

// Rgb is a 24 bit color value represented with a 32 bit int
// in the conventional way.  This is expected to be convenient
// for the programmer in many cases.
type Rgb int32

// Pixel has r, g, and b as separate fields.  This is used as
// the in-memory representation of a bitmap.
type Pixel struct {
    R, G, B byte
}

// Pixel returns a new Pixel from a Rgb value
func (c Rgb) Pixel() Pixel {
    return Pixel{R: byte(c >> 16), G: byte(c >> 8), B: byte(c)}
}

// Rgb returns a single Rgb value computed from rgb fields of a Pixel
// of a Pixel.
func (p Pixel) Rgb() Rgb {
    return Rgb(p.R)<<16 | Rgb(p.G)<<8 | Rgb(p.B)
}

// Bitmap is the in-memory representation, or image storage type of a bitmap.
// Zero value for type is a valid zero-size bitmap.
// The only exported field is Comments.  Remaining fields have interdepencies
// that are managed by package code and so should not be directly accessed
// from outside the package.
type Bitmap struct {
    Comments   []string
    rows, cols int
    px         []Pixel   // all pixels as a single slice, row major order
    pxRow      [][]Pixel // rows of pixels as slices of px
}

const creator = "# Creator: Rosetta Code http://rosettacode.org/"

// New is a Bitmap "constructor."  Parameters x and y are extents.
// That is, the new bitmap will have x columns and y rows.
func NewBitmap(x, y int) (b *Bitmap) {
    b = &Bitmap{
        Comments: []string{creator},
        rows:     y, // named fields here to prevent possible mix-ups.
        cols:     x,
        px:       make([]Pixel, x*y),
        pxRow:    make([][]Pixel, y),
    }
    // Note rows of pixels are not allocated separately.
    // Rather the whole bitmap is allocted in one chunk as px.
    // This simplifies allocation and maintains locality.
    x0, x1 := 0, x
    for i := range b.pxRow {
        b.pxRow[i] = b.px[x0:x1] // slice operation. does no allocation.
        x0, x1 = x1, x1+x
    }
    return b
}

// Extent returns bitmap dimensions.
func (b *Bitmap) Extent() (cols, rows int) {
    return b.cols, b.rows
}

// Fill entire bitmap with solid color.
func (b *Bitmap) Fill(p Pixel) {
    for i := range b.px {
        b.px[i] = p
    }
}

func (b *Bitmap) FillRgb(c Rgb) {
    b.Fill(c.Pixel())
}

// Set a single pixel color value.
// Clips to bitmap boundaries.
// Returns true if pixel was set, false if clipped.
func (b *Bitmap) SetPx(x, y int, p Pixel) bool {
    defer func() { recover() }()
    b.pxRow[y][x] = p
    return true
}

func (b *Bitmap) SetPxRgb(x, y int, c Rgb) bool {
    return b.SetPx(x, y, c.Pixel())
}

// Note:  Clipping to bitmap boundaries is needed for program correctness
// but is otherwise not required by the task.  It is implemented with the
// combination of pxRow and the deferred recover.  SetPx, GetPx return the
// clipping result as a way for higher level graphics functions to track
// plotting and clipping status.  As this is not required by tasks though,
// it is generally not implemented.

// Get a single pixel color value.
// Returns pixel and ok=true if coordinates are within bitmap boundaries.
// Returns ok=false if coordinates are outside bitmap boundaries.
func (b *Bitmap) GetPx(x, y int) (p Pixel, ok bool) {
    defer func() { recover() }()
    return b.pxRow[y][x], true
}

func (b *Bitmap) GetPxRgb(x, y int) (Rgb, bool) {
    p, ok := b.GetPx(x, y)
    if !ok {
        return 0, false
    }
    return p.Rgb(), true
}

Haskell

We implement the Image type as an STArray so that we can use it in an imperative fashion in the ST monad.

module Bitmap(module Bitmap) where
 
import Control.Monad
import Control.Monad.ST
import Data.Array.ST

newtype Pixel = Pixel (Int, Int) deriving Eq

instance Ord Pixel where
    compare (Pixel (x1, y1)) (Pixel (x2, y2)) =
        case compare y1 y2 of
            EQ -> compare x1 x2
            v  -> v

instance Ix Pixel where
{- This instance differs from the one for (Int, Int) in that
the ordering of indices is
  (0,0), (1,0), (2,0), (0,1), (1,1), (2,1)
instead of
  (0,0), (0,1), (1,0), (1,1), (2,0), (2,1). -}
    range (Pixel (xa, ya), Pixel (xz, yz)) =
        [Pixel (x, y) | y <- [ya .. yz], x <- [xa .. xz]]
    index (Pixel (xa, ya), Pixel (xz, _)) (Pixel (xi, yi)) =
        (yi - ya)*(xz - xa + 1) + (xi - xa)
    inRange (Pixel (xa, ya), Pixel (xz, yz)) (Pixel (xi, yi)) =
        not $ xi < xa || xi > xz || yi < ya || yi > yz
    rangeSize (Pixel (xa, ya), Pixel (xz, yz)) =
        (xz - xa + 1) * (yz - ya + 1)

instance Show Pixel where
    show (Pixel p) = show p

class Ord c => Color c where
    luminance :: c -> Int
     -- The Int should be in the range [0 .. 255].
    black, white :: c
    toNetpbm :: [c] -> String
    fromNetpbm :: [Int] -> [c]
    netpbmMagicNumber, netpbmMaxval :: c -> String
      {- The argument to these two functions is ignored; the
      parameter is only for typechecking. -}

newtype Color c => Image s c = Image (STArray s Pixel c)

image :: Color c => Int -> Int -> c -> ST s (Image s c)
{- Creates a new image with the given width and height, filled
with the given color. -}
image w h = liftM Image .
    newArray (Pixel (0, 0), Pixel (w - 1, h - 1))

listImage :: Color c => Int -> Int -> [c] -> ST s (Image s c)
{- Creates a new image with the given width and height, with
each pixel set to the corresponding element of the given list. -}
listImage w h = liftM Image .
    newListArray (Pixel (0, 0), Pixel (w - 1, h - 1))

dimensions :: Color c => Image s c -> ST s (Int, Int)
dimensions (Image i) = do
    (_, Pixel (x, y)) <- getBounds i
    return (x + 1, y + 1)

getPix :: Color c => Image s c -> Pixel -> ST s c
getPix (Image i) = readArray i

getPixels :: Color c => Image s c -> ST s [c]
getPixels (Image i) = getElems i

setPix :: Color c => Image s c -> Pixel -> c -> ST s ()
setPix (Image i) = writeArray i

fill :: Color c => Image s c -> c -> ST s ()
fill (Image i) c = getBounds i >>= mapM_ f . range
  where f p = writeArray i p c

mapImage :: (Color c, Color c') =>
    (c -> c') -> Image s c -> ST s (Image s c')
mapImage f (Image i) = liftM Image $ mapArray f i

This module provides an instance of Color.

module Bitmap.RGB(module Bitmap.RGB) where

import Bitmap
import Control.Monad.ST

newtype RGB = RGB (Int, Int, Int) deriving (Eq, Ord)

instance Color RGB where
    luminance (RGB (r, g, b)) = round x
      where x = 0.2126*r' + 0.7152*g' + 0.0722*b'
            (r', g', b') = (toEnum r, toEnum g, toEnum b)
    black = RGB (0,   0,   0)
    white = RGB (255, 255, 255)
    toNetpbm = concatMap f
      where f (RGB (r, g, b)) = [toEnum r, toEnum g, toEnum b]
    fromNetpbm [] = []
    fromNetpbm (r : g : b : rest) = RGB (r, g, b) : fromNetpbm rest
    netpbmMagicNumber _ = "P6"
    netpbmMaxval _ = "255"

toRGBImage :: Color c => Image s c -> ST s (Image s RGB)
toRGBImage = mapImage $ f . luminance
  where f x = RGB (x, x, x)

Icon and Unicon

The language has a built-in window data type with associated graphics primitives. A bitmap is just a window that isn't visible on-screen at the moment.

procedure makebitmap(width,height)
   return open("bitmap", "g", "canvas=hidden",
             "size="||width||","||height)
end
procedure fillimage(w,color)
   Fg(w,color)
   FillRectangle(w)
end
procedure setpixel(w,x,y,color)
   Fg(w,color)
   DrawPixel(x,y)
end
procedure getpixel(w,x,y)
   return Pixel(w,x,y)
end

J

A number of addon packages are available for J that work with common image formats (including PPM), but here we will show a basic bitmap storage type as per the task description.

The structure is a 3-dimensional array of numbers. The shape of the array is height by width by 3. Each 1-dimensional cell of size 3 contains R, G and B numbers, in that order. Indexing is zero based. (We could instead have encoded RGB in a single integer...)

No parameter validity checks are currently implemented.

In J, allocating an uninitialized image would not normally be separated from creating the colored image, so makeRGB allows the specification of color during allocation. As a monad, makeRGB creates a black image with the specified height and width. It can also take a left argument (dyadic form) specifying the color(s) of the image. fillRGB requires a left argument specifying the color(s), but takes a bitmap (RGB) structure as the right argument.

Solution:

makeRGB=: 0&$: : (($,)~ ,&3)
fillRGB=: makeRGB }:@$
setPixels=: (1&{::@[)`(<"1@(0&{::@[))`]}
getPixels=: <"1@[ { ]

Examples:

   myimg=: makeRGB 5 8               NB. create a bitmap with height 5 and width 8 (black)
   myimg=: 255 makeRGB 5 8           NB. create a white bitmap with height 5 and width 8
   myimg=: 127 makeRGB 5 8           NB. create a gray bitmap with height 5 and width 8
   myimg=: 0 255 0 makeRGB 5 8       NB. create a green bitmap with height 5 and width 8
   myimg=: 0 0 255 fillRGB myimg     NB. fill myimg with blue
   colors=: 0 255 {~ #: i.8          NB. black,blue,green,cyan,red,magenta,yellow,white
   myimg=: colors fillRGB myimg      NB. fill myimg with vertical stripes of colors
   2 4 getPixels myimg               NB. get the pixel color from point (2, 4)
255 0 0

   myimg=: (2 4 ; 255 255 255) setPixels myimg   NB. set pixel at point (2, 4) to white
   2 4 getPixels myimg               NB. get the pixel color from point (2, 4)
255 255 255

   }:$ myimg                         NB. get height and width of the image
5 8

getPixels and setPixels are generalized to set and get lists/arrays of pixels.

pixellist=: ,"0/~ i. 10  NB. row and column indices for 10 by 10 block of pixels

NB. create 10 by 10 block of magenta pixels in the middle of a 300 by 300 green image
myimg=: ((145 + pixellist) ; 255 0 255) setPixels 0 255 0 makeRGB 300 300

NB. get pixel color for 10x10 block offset from magenta block
subimg=: (140 + pixellist) getPixels myimg

To display the image in a window at any point for verification:

require 'viewmat'
viewRGB=: [: viewrgb 256&#.

viewRGB myimg

Note that height comes before width here. This is inconsistent with marketing of display resolutions, but matches J's treatment of dimensions.

Java

Solution

Library: AWT
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;

public class BasicBitmapStorage {

    private final BufferedImage image;

    public BasicBitmapStorage(int width, int height) {
        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    }

    public void fill(Color c) {
        Graphics g = image.getGraphics();
        g.setColor(c);
        g.fillRect(0, 0, image.getWidth(), image.getHeight());
    }

    public void setPixel(int x, int y, Color c) {
        image.setRGB(x, y, c.getRGB());
    }

    public Color getPixel(int x, int y) {
        return new Color(image.getRGB(x, y));
    }

    public Image getImage() {
        return image;
    }
}

Test Program

Library: JUnit
import static org.junit.Assert.assertEquals;

import java.awt.Color;
import org.junit.Test;

public class BasicBitmapStorageTest {

    @Test
    public void testHappy() {
        int width = 640;
        int height = 480;

        BasicBitmapStorage bbs = new BasicBitmapStorage(width, height);
        bbs.fill(Color.CYAN);
        bbs.setPixel(width / 2, height / 2, Color.BLACK);
        Color c1 = bbs.getPixel(width / 2, height / 2);
        Color c2 = bbs.getPixel(20, 20);

        assertEquals(Color.BLACK, c1);
        assertEquals(Color.CYAN, c2);
    }
}

JavaScript

JavaScript can interact with a drawing context using the HTML5 Canvas API.

// Set up the canvas
var canvas = document.createElement("canvas"),
    ctx = canvas.getContext("2d"),
    width = 400, height = 400;

ctx.canvas.width = width;
ctx.canvas.height = height;

// Optionaly add it to the current page
document.body.appendChild(canvas);

// Draw an image
var img = document.createElement("img");
img.onload = function(){
    // Draw the element into the top-left of the canvas
    ctx.drawImage(img, 0, 0);
};
img.src = "//placehold.it/400x400";

// Fill the canvas with a solid blue color
ctx.fillStyle = "blue";
ctx.fillRect(0, 0, width, height);

// Place a black pixel in the middle
// Note that a pixel is a 1 by 1 rectangle
// This is the fastest method as of 2012 benchmarks
ctx.fillStyle = "black";
ctx.fillRect(width / 2, height / 2, 1, 1);

Julia

Works with: Julia version 0.6

Using packages (Images.jl, Colors.jl):

using Images, Colors

Base.hex(p::RGB{T}) where T = join(hex(c(p), 2) for c in (red, green, blue))
function showhex(m::Matrix{RGB{T}}, pad::Integer=4) where T
    for r in 1:size(m, 1)
        println(" " ^ pad, join(hex.(m[r, :]), " "))
    end
end

w, h = 5, 7
cback = RGB(1, 0, 1)
cfore = RGB(0, 1, 0)

img = Array{RGB{N0f8}}(h, w);
println("Uninitialized image:")
showhex(img)

fill!(img, cback)
println("\nImage filled with background color:")
showhex(img)

img[2, 3] = cfore
println("\nImage with a pixel set for foreground color:")
showhex(img)
Output:
Uninitialized image:
    10DFF8 7F0000 F84A00 0030DA 007F00
    4A007F B0DDF8 7F0000 F84A00 00D0DB
    0000F0 4A007F D0D9F8 7F0000 F84A00
    DFF84A 000050 4A007F 50DAF8 7F0000
    007F00 D9F84A 000010 4A007F 30DCF8
    0050E0 007F00 DAF84A 000050 4A007F
    F84A00 00B0D9 007F00 DBF84A 000050

Image filled with background color:
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF

Image with a pixel set for foreground color:
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF 00FF00 FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF
    FF00FF FF00FF FF00FF FF00FF FF00FF

KonsolScript

function main() {
  Var:Number shape;
  
  Image:New(50, 50, shape)
  Draw:RectFill(0, 0, 50, 50, 0xFF0000, shape)  //one to fill an image with a plain RED color
  
  Draw:Pixel(30, 30, 0x0000FF, shape)           //set a given pixel at (30,30) with a BLUE color
  
  while (B1 == false) {
    Image:Blit(10, 10, shape, screen)
    Screen:Render()
  }
}

Kotlin

Translation of: Java
// version 1.1.4-3

import java.awt.Color
import java.awt.Graphics
import java.awt.image.BufferedImage

class BasicBitmapStorage(width: Int, height: Int) {
    val image = BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR)

    fun fill(c: Color) {
        val g = image.graphics
        g.color = c
        g.fillRect(0, 0, image.width, image.height)
    }

    fun setPixel(x: Int, y: Int, c: Color) = image.setRGB(x, y, c.getRGB())

    fun getPixel(x: Int, y: Int) = Color(image.getRGB(x, y))
}

fun main(args: Array<String>) {
    val width = 640
    val height = 480
    val bbs = BasicBitmapStorage(width, height)
    with (bbs) {
        fill(Color.cyan)
        setPixel(width / 2, height / 2, Color.black)
        val c1 = getPixel(width / 2, height / 2)
        val c2 = getPixel(20, 20)
        print("The color of the pixel at (${width / 2}, ${height / 2}) is ")
        println(if (c1 == Color.black) "black" else "unknown")
        print("The color of the pixel at (120, 120) is ")
        println(if (c2 == Color.cyan) "cyan" else "unknown")
    }
}
Output:
The color of the pixel at (320, 240) is black
The color of the pixel at (120, 120) is cyan

Lingo

-- Creates a new image object of size 640x480 pixel and 32-bit color depth
img = image(640, 480, 32)

-- Fills image with plain red
img.fill(img.rect, rgb(255,0,0))

-- Gets the color value of the pixel at point (320, 240)
col = img.getPixel(320, 240)

-- Changes the color of the pixel at point (320, 240) to black
img.setPixel(320, 240, rgb(0,0,0))

LiveCode

LiveCode has built in support for importing and exporting PBM, JPEG, GIF, BMP or PNG graphics formats

   -- create an image container box at the center of the current stack window with default properties
   create image "test"
   -- programtically choose the paint bucket tool
   choose bucket tool
   -- LiveCode engine has built-in color keywords:
   set the brushColor to "dark green"
   -- programtically mouse click at the center of image container box to fill
   click at the loc of image "test"
   -- get the RGBA values of the first pixel in the image box
   put byteToNum(byte 1 of the imageData of image "test") into tRed
   put byteToNum(byte 2 of the imageData of image "test") into tGreen
   put byteToNum(byte 3 of the imageData of image "test") into tBlue
   put byteToNum(byte 4 of the imageData of image "test") into tAlpha
   -- log message the info in the message box
   put "First Pixel Color is Red:"& tRed &" Green:"& tGreen &" Blue:"& tBlue &" Transparency:"& tAlpha
   -- just for fun replace the contents with RosettaCode logo
   wait 2 seconds
   set the filename of image "test" to "http://rosettacode.org/mw/title.png"
    -- the next line is copy of the Write a PPM task:
   export image "test" to file "~/Test.PPM" as paint -- paint format is one of PBM, PGM, or PPM

Lua

Original

function Allocate_Bitmap( width, height )
    local bitmap = {}
    for i = 1, width do
        bitmap[i] = {}
        for j = 1, height do
            bitmap[i][j] = {}
        end
    end
    return bitmap
end

function Fill_Bitmap( bitmap, color )
    for i = 1, #bitmap do
        for j = 1, #bitmap[1] do
            bitmap[i][j] = color
        end
    end
end

function Get_Pixel( bitmap, x, y )
    return bitmap[x][y]
end

This can be used like:

bitmap = Allocate_Bitmap( 100, 50 )
Fill_Bitmap( bitmap, { 15, 200, 80 } )
pixel = Get_Pixel( bitmap, 20, 25 )
print( pixel[1], pixel[2], pixel[3] )

Alternate

A more object-oriented and extensible approach for easier re-use elsewhere.

local Bitmap = {
  new = function(self, width, height)
    local instance = setmetatable({ width=width, height=height }, self)
    instance:alloc()
    return instance
  end,
  alloc = function(self)
   self.pixels = {}
    for y = 1, self.height do
      self.pixels[y] = {}
      for x = 1, self.width do
        self.pixels[y][x] = 0x00000000
      end
    end
  end,
  clear = function(self, c)
    for y = 1, self.height do
      for x = 1, self.width do
        self.pixels[y][x] = c or 0x00000000
      end
    end
  end,
  get = function(self, x, y)
    x, y = math.floor(x+1), math.floor(y+1) -- given 0-based indices, use 1-based indices
    if ((x>=1) and (x<=self.width) and (y>=1) and (y<=self.height)) then
      return self.pixels[y][x]
    else
      return nil
    end
  end,
  set = function(self, x, y, c)
    x, y = math.floor(x+1), math.floor(y+1) -- given 0-based indices, use 1-based indices
    if ((x>=1) and (x<=self.width) and (y>=1) and (y<=self.height)) then
      self.pixels[y][x] = c or 0x00000000
    end
  end,
}
Bitmap.__index = Bitmap
setmetatable(Bitmap, { __call = function (t, ...) return t:new(...) end })

Usage:

local bitmap = Bitmap(32,32)

-- default pixel representation is 32-bit packed ARGB on [0,255]
bitmap:clear(0xFFFF0000) -- fill with red
bitmap:set(1, 1, 0xFF00FF00) -- one green pixel
bitmap:set(2, 2, 0xFF0000FF) -- one blue pixel
print(string.format("pixel at 0,0 = %x", bitmap:get(0,0)))
print(string.format("pixel at 1,1 = %x", bitmap:get(1,1)))
print(string.format("pixel at 2,2 = %x", bitmap:get(2,2)))

-- but note that pixel representation is agnostic..
-- (it's just a wrapper around a 2d-array of any valid type)

-- want to switch to RGB-tuple on [0,1]??
bitmap:clear({1,0,0}) -- fill with red
bitmap:set(1, 1, {0,1,0}) -- one green pixel
bitmap:set(2, 2, {0,0,1}) -- one blue pixel
print(string.format("pixel at 0,0 = %s", table.concat(bitmap:get(0,0),", ")))
print(string.format("pixel at 1,1 = %s", table.concat(bitmap:get(1,1),", ")))
print(string.format("pixel at 2,2 = %s", table.concat(bitmap:get(2,2),", ")))

-- or strings??
bitmap:clear("red") -- fill with red
bitmap:set(1, 1, "green") -- one green pixel
bitmap:set(2, 2, "blue") -- one blue pixel
print(string.format("pixel at 0,0 = %s", bitmap:get(0,0)))
print(string.format("pixel at 1,1 = %s", bitmap:get(1,1)))
print(string.format("pixel at 2,2 = %s", bitmap:get(2,2)))

Caveat: Just be aware that as currently written the storage of complex types are referenced rather than copied. So, for example, using the clear() method with a table representing an RGB-tuple, will store the same identical reference throughout the bitmap - so direct modification of any one pixel's internal components would affect all other pixels as well. You should override the clear() method as appropriate to better support your desired pixel representation if this is not the behavior you desire.

Output:
pixel at 0,0 = ffff0000
pixel at 1,1 = ff00ff00
pixel at 2,2 = ff0000ff
pixel at 0,0 = 1, 0, 0
pixel at 1,1 = 0, 1, 0
pixel at 2,2 = 0, 0, 1
pixel at 0,0 = red
pixel at 1,1 = green
pixel at 2,2 = blue

M2000 Interpreter

The easy way is to make a function to return an object with all functions on it, for specific image. We have to make the image in a way to render it to screen. The render statement get data in a string using a header of 12 characters (24 bytes). Raster lines are in down-top order. So last raster line is the top one. Also RGB is BGR in this data structure. Raster lines has to be aligned proper, so we may have add some bytes.

There are four functions (lambda functions) in the returned group, each of them has closures, an one of that closure is a pointer to a buffer object. We use this object to set and get pixels.

First two functions are for set and get pixel. Third return image as a string. Forth function copy an image as string to buffer, if they have the same width and height (else we get error)

P3 ppm

\ Bitmap width in pixels, height in pixels
\ Return a group object with some lambda as members: SetPixel, GetPixel, Image$
\ copyimage
\ using Copy x, y Use Image$ we can display image$ to x, y  as twips
\ we can use  x*twipsx, y*twipsy  for x,y as  pixels
Function Bitmap (x as long, y as long) {
      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
            }   
            \\ union pad+hline
            hline as rgb*x
      }

      Structure Raster {
            magic as integer*4
            w as integer*4
            h as integer*4
            lines as rasterline*y
      }
      Buffer Clear Image1 as Raster
      \\ 24 chars as header to be used from bitmap render build in functions
      Return Image1, 0!magic:="cDIB", 0!w:=Hex$(x,2), 0!h:=Hex$(y, 2)
      \\ fill white (all 255)
      \\ Str$(string) convert to ascii, so we get all characters from words  width to byte width
      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))
      }
      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"
      }
      Group Bitmap {
            SetPixel=SetPixel
            GetPixel=GetPixel
            Image$=StrDib$
            Copy=CopyImage
      }
      =Bitmap
}
A=Bitmap(100,100)
Call A.SetPixel(50,50, color(128,0,255))
Print A.GetPixel(50,50)=color(128,0,255)
\\ display image to screen at 100, 50 pixel
copy 100*twipsx,50*twipsy use A.Image$()
A1=Bitmap(100,100)
Call A1.copy(A.Image$())
copy 500*twipsx,50*twipsy use A1.Image$()

P6 ppm

Need Version 9.4, Rev >=19

Module  P6 {
      Function Bitmap  {
            def x as long, y as long, Import 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
                        If p6$=str$("P6") 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" 
                        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))
            }
            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
                  Buffer pad as byte*3
                  For y1= 0 to y-1 {
                        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
                        }
                        m=where mod 4 : if m<>0 then where+=4-m
                  } 
            }
            if Import then {
                  x0=x-1 : where=0
                  Buffer Pad1 as byte*3
                  For y1=y-1 to 0 {
                        For x1=0 to x0 {Get #f, Pad1 : Push Eval(pad1, 2) : Return pad1, 2:=Eval(pad1, 0), 0:=Number                                    
                              Return Image1, 0!linesB!where:=Eval$(Pad1) : where+=3}
                        m=where mod 4 : if m<>0 then where+=4-m}
            }
            Group Bitmap {
                  SetPixel=SetPixel
                  GetPixel=GetPixel
                  Image$=StrDib$
                  Copy=CopyImage
                  ToFile=Export2File
            }
            =Bitmap
      }
      A=Bitmap(150,100)
      For i=0  to 98  {
            Call A.SetPixel(i, i, 0)
            Call A.SetPixel(99, i, 0)
      }
      Call A.SetPixel(i,i,0)
      Copy 200*twipsx, 100*twipsy use A.Image$()
      Profiler
      Open "a.ppm" for output as #F
      Call A.tofile(f)
      Close #f
      Print Filelen("a.ppm")
      Print Timecount/1000;"sec"
      Profiler
      Image A.Image$() Export "a.jpg", 100  ' per cent quality
      Print Filelen("a.jpg")
      Image A.Image$() Export "a1.jpg", 10  ' per cent quality
      Print Filelen("a1.jpg")
      Image A.Image$() Export "a.bmp"
      Print Filelen("a.bmp")  ' no compression
      Print Timecount/1000;"sec"
      Move 5000,5000   ' twips
      Image "a.jpg"
      Move 5000,8000
      Image "a1.jpg"
      Move 8000, 5000
      Image "a.bmp"     
}
P6

Export using M2000 code for ppm is slower than using internal jpg and bmp encoders. Jpg encoder has a 100% quality, and because this image is black and white we get the best compression. Time 0.304sec is for three exports, two jpg and one bmp.

Output:
     45049
47.3661341sec
      1018
       691
     45254
0.3040944sec

Maple

allocateImg := proc(width, height)
	return Array(1..width, 1..height, 1..3);
end proc:
fillColor := proc(img, rgb::list)
	local i;
	for i from 1 to 3 do
		img[..,..,i] := map(x->rgb[i], img[..,..,i]):
	end do:
end proc:
setColor := proc(x, y, img, rgb::list)
	local i:
	for i from 1 to 3 do
		img[x,y,i] := rgb[i]:
	end do:
end proc:
getColor := proc(x,y,img)
	local rgb,i:
	rgb := Array(1..3):
	for i from 1 to 3 do
		rgb(i) := img[x,y,i]:
	end do:
	return rgb:
end proc:
Use:
a := allocateImg(200,200);
fillColor(a,[255,223,0]);
setColor(150,150, a, [0,0,0]);
getColor(150,150,a);
#Output the image
ImageTools:-Embed(ImageTools:-Create(a))

Mathematica / Wolfram Language

In Mathematica 7/8:

img = Image[ConstantArray[{1, 0, 0}, {1000, 1000}]];
img = ReplacePart[img, {1, 1, 1} -> {0, 0, 1}];
ImageValue[img, {1, 1}]

In Mathematica 9:

img = Image[ConstantArray[{1, 0, 0}, {1000, 1000}]];
img = ReplacePixelValue[img, {1, 1} -> {0, 0, 1}];
ImageValue[img, {1, 1}]

MATLAB

Save this in a file named Bitmap.mat in a folder named @Bitmap in your MATLAB root directory.

%Bitmap class
%
%Implements a class to manage bitmap images without the need for the
%various conversion and display functions
%
%Available functions:
%
%fill(obj,color)
%setPixel(obj,pixel,color)
%getPixel(obj,pixel,[optional: color channel])
%display(obj)
%disp(obj)
%plot(obj)
%image(obj)
%save(obj)
%open(obj)

classdef Bitmap

    %% Public Properties
    properties

        %Channel arrays
        red;
        green;
        blue;

    end

    %% Public Methods
    methods

        %Creates image and defaults it to black
        function obj = Bitmap(width,height)
            obj.red   = zeros(height,width,'uint8');
            obj.green = zeros(height,width,'uint8');
            obj.blue  = zeros(height,width,'uint8');
        end % End Bitmap Constructor

        %Fill the image with a specified color
        %color = [red green blue] max for each is 255
        function fill(obj,color)
            obj.red(:,:)   = color(1);
            obj.green(:,:) = color(2);
            obj.blue(:,:)  = color(3);
            assignin('caller',inputname(1),obj); %saves the changes to the object
        end

        %Set a pixel to a specified color
        %pixel = [x y]
        %color = [red green blue]
        function setPixel(obj,pixel,color)
            obj.red(pixel(2),pixel(1))   = color(1);
            obj.green(pixel(2),pixel(1)) = color(2);
            obj.blue(pixel(2),pixel(1))  = color(3);
            assignin('caller',inputname(1),obj); %saves the changes to the object
        end

        %Get pixel color
        %pixel = [x y]
        %varargin can be:
        %  no input for all channels
        %  'r' or 'red' for red channel
        %  'g' or 'green' for green channel
        %  'b' or 'blue' for blue channel
        function color = getPixel(obj,pixel,varargin)

            if( ~isempty(varargin) )
                switch (varargin{1})
                    case {'r','red'}
                        color = obj.red(pixel(2),pixel(1));
                    case {'g','green'}
                        color = obj.red(pixel(2),pixel(1));
                    case {'b','blue'}
                        color = obj.red(pixel(2),pixel(1));
                end
            else
                color = [obj.red(pixel(2),pixel(1)) obj.green(pixel(2),pixel(1)) obj.blue(pixel(2),pixel(1))];
            end

        end

        %Display the image
        %varargin can be:
        %  no input for all channels
        %  'r' or 'red' for red channel
        %  'g' or 'green' for green channel
        %  'b' or 'blue' for blue channel
        function display(obj,varargin)
            
            if( ~isempty(varargin) )
                switch (varargin{1})
                    case {'r','red'}
                        image(obj.red)
                    case {'g','green'}
                        image(obj.green)
                    case {'b','blue'}
                        image(obj.blue)
                end
                
                colormap bone;
            else
                bitmap = cat(3,obj.red,obj.green,obj.blue);
                image(bitmap);
            end
        end

        %Overload several commonly used display functions
        function disp(obj,varargin)
            display(obj,varargin{:});
        end

        function plot(obj,varargin)
            display(obj,varargin{:});
        end

        function image(obj,varargin)
            display(obj,varargin{:});
        end

        %Saves the image
        function save(obj)

            %Open file dialogue
            [fileName,pathName,success] = uiputfile({'*.bmp','Bitmap Image (*.bmp)'},'Save Bitmap As');

            if( not(success == 0) )
                imwrite(cat(3,obj.red,obj.green,obj.blue),[pathName fileName],'bmp'); %Write image file to disk
                disp('Save Complete');
            end
        end

        %Opens an image and overwrites what is currently stored
        function success = open(obj)

            %Open file dialogue
            [fileName,pathName,success] = uigetfile({'*.bmp','Bitmap Image (*.bmp)'},'Open Bitmap ');

            if( not(success == 0) )

                channels = imread([pathName fileName], 'bmp'); %returns color indexed data

                %Store each channel
                obj.red   = channels(:,:,1);
                obj.green = channels(:,:,2);
                obj.blue  = channels(:,:,3);

                assignin('caller',inputname(1),obj); %saves the changes to the object
                success = true;
                return
            else
                success = false;
                return
            end
        end


    end %methods
end %classdef

Sample Usage:

>> img = Bitmap(20,30);
>> img.fill([30 30 150]);
>> img.setPixel([10 15],[20 130 66]);
>> disp(img)
>> img.getPixel([10 15])

ans =

   20  130   66

>> img.getPixel([10 15],'red')

ans =

   20

>> img.save()
Save Complete

MAXScript

MAXScript provides a built-in Bitmap class.

local myBitmap = bitmap 512 512

Filling the image with a single colour can be accomplished at creation time by setting the color property.

local myBitmap = bitmap 512 512 color:(color 128 128 128)

Use setPixels to set the colour of a pixel. This function takes an array of colours and is optimised to set the colours of a whole row of pixels.

setPixels myBitmap [256, 256] #((color 255 255 255))

Use getPixels to retrieve the colour of a pixel. As with setPixels, this function is optimised to retrieve one row at a time as an array of colour values.

local myPixel = getPixels myBitmap [256, 256] 1

MiniScript

This GUI implementation is for use with Mini Micro.

// MiniMicro version of MiniScript has all the
// necessary methods built-in to complete this task.
width = 256
height = 256
colr = color.aqua

// Create the image with specified width/heigh. With
// no parameters, it defaults width/height to 64 and
// color to black
img = Image.create(width, height, colr)

// Create a diagonal line of multiple colors. Uses
// Cartesian coordinates so (0, 0) is lower left corner.
for i in range(0, 255)
	img.setPixel i, i, color.rgb(i, i, i)
end for

// Get pixel color as RGBA hex values
print "Color at pixel (100, 100): " + img.pixel(100, 100)
print "Color at pixel (0, 0): " + img.pixel(0, 0)
print "Color at pixel (127, 127): " + img.pixel(127, 127)
print "Color at pixel (255, 255): " + img.pixel(255, 255)

// Display the image, resizing it to 127 x 127
gfx.drawImage img, 0, 0, 127, 127

// Save the file - accepted file extensions:
// tga, jpg, jpeg, and png (retains transparency)
// Optional third parameter is JPG compression quality.
file.saveImage "/usr/test.png", img

Modula-3

Since this code is for use with other tasks, it uses an interface as well as the implementation module.

INTERFACE Bitmap;

TYPE UByte = BITS 8 FOR [0 .. 16_FF];
     Pixel = RECORD R, G, B: UByte; END;
     Point = RECORD x, y: UByte; END;
     T = REF ARRAY OF ARRAY OF Pixel;

CONST
  Black = Pixel{0, 0, 0};
  White = Pixel{255, 255, 255};
  Red = Pixel{255, 0, 0};
  Green = Pixel{0, 255, 0};
  Blue = Pixel{0, 0, 255};
  Yellow = Pixel{255, 255, 0};

EXCEPTION BadImage;
          BadColor;

PROCEDURE NewImage(height, width: UByte): T RAISES {BadImage};
PROCEDURE Fill(VAR pic: T; color: Pixel);
PROCEDURE GetPixel(VAR pic: T; point: Point): Pixel RAISES {BadColor};
PROCEDURE SetPixel(VAR pic: T; point: Point; color: Pixel);

END Bitmap.
MODULE Bitmap;

PROCEDURE NewImage(height, width: UByte): T RAISES {BadImage} =
  (* To make things easier, limit image size to also 
     be UByte (0 to 255), and to have equal dimensions. *)
  BEGIN
    IF height # width THEN
      RAISE BadImage;
    END;
    RETURN NEW(T, height, width);
  END NewImage;

PROCEDURE Fill(VAR pic: T; color: Pixel) =
  BEGIN
    FOR i := FIRST(pic^) TO LAST(pic^) DO
      FOR j := FIRST(pic[0]) TO LAST(pic[0]) DO
        pic[i,j] := color;
      END;
    END;
  END Fill;

PROCEDURE GetPixel(VAR pic: T; point: Point): Pixel RAISES {BadColor} =
  VAR pixel := pic[point.x, point.y];
  BEGIN
    IF pixel = White THEN
      RETURN White;
    ELSIF pixel = Black THEN
      RETURN Black;
    ELSIF pixel = Red THEN
      RETURN Red;
    ELSIF pixel = Green THEN
      RETURN Green;
    ELSIF pixel = Blue THEN
      RETURN Blue;
    ELSIF pixel = Yellow THEN
      RETURN Yellow;
    ELSE
      RAISE BadColor;
    END;
  END GetPixel;

PROCEDURE SetPixel(VAR pic: T; point: Point; color: Pixel) =
  BEGIN
    pic[point.x, point.y] := color;
  END SetPixel;
  
BEGIN
END Bitmap.

Nim

type
  Luminance* = uint8
  Index* = int

  Color* = tuple
    r, g, b: Luminance

  Image* = ref object
    w*, h*: Index
    pixels*: seq[Color]

  Point* = tuple
    x, y: Index

proc color*(r, g, b: SomeInteger): Color =
  ## Build a color value from R, G and B values.
  result.r = r.uint8
  result.g = g.uint8
  result.b = b.uint8

const
  Black* = color(  0,   0,   0)
  White* = color(255, 255, 255)

proc newImage*(width, height: int): Image =
  ## Create an image with given width and height.
  new(result)
  result.w = width
  result.h = height
  result.pixels.setLen(width * height)

iterator indices*(img: Image): Point =
  ## Yield the pixels coordinates as tuples.
  for y in 0 ..< img.h:
    for x in 0 ..< img.w:
      yield (x, y)

proc `[]`*(img: Image; x, y: int): Color =
  ## Get a pixel RGB value.
  img.pixels[y * img.w + x]

proc `[]=`*(img: Image; x, y: int; c: Color) =
  ## Set a pixel RGB value to given color.
  img.pixels[y * img.w + x] = c

proc fill*(img: Image; color: Color) =
  ## Fill the image with a color.
  for x, y in img.indices:
    img[x, y] = color

proc print*(img: Image) =
  ## Output an ASCII representation of the image.
  for x, y in img.indices:
    if x mod img.w == 0:
      stdout.write '\n'
    stdout.write if img[x, y] == White: '.' else: 'H'
  stdout.write '\n'

when isMainModule:
  var img = newImage(100, 20)
  img.fill color(255, 255, 255)
  img[1, 2] = color(255, 0, 0)
  img[3, 4] = img[1, 2]
  img.print

OCaml

let new_img ~width ~height =
  let all_channels =
    let kind = Bigarray.int8_unsigned
    and layout = Bigarray.c_layout
    in
    Bigarray.Array3.create kind layout 3 width height
  in
  let r_channel = Bigarray.Array3.slice_left_2 all_channels 0
  and g_channel = Bigarray.Array3.slice_left_2 all_channels 1
  and b_channel = Bigarray.Array3.slice_left_2 all_channels 2
  in
  (all_channels,
   r_channel,
   g_channel,
   b_channel)

and here is the type of the raster image this function returns:

type raster =
  (int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array3.t *
  (int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array2.t *
  (int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array2.t *
  (int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array2.t

What is particular with this allocation and its associated type is that there is not only one buffer for each RGB channel, but also an additionnal one that handles all the three channels, and what is important here is that it is not additionnal memory, the memory is shared, so there are 2 ways to access the raster buffer: through the separated RGB channels, or through the joint channel (all_channels).

This solution have a lot of advantages across a more naive one: this type is compatible to memory-map a file (a ppm file for instance, where the data is not compressed), the buffer can be shared/exchanged with C (for OpenGL textures for instance), etc.

A more naive form would be this one:

let new_img ~width ~height =
  let r_channel, g_channel, b_channel =
    let kind = Bigarray.int8_unsigned
    and layout = Bigarray.c_layout
    in
    (Bigarray.Array2.create kind layout width height,
     Bigarray.Array2.create kind layout width height,
     Bigarray.Array2.create kind layout width height)
  in
  (r_channel,
   g_channel,
   b_channel)

Here are the functions to fill with a color and to set one given pixel:

let fill_img ~img:(_, r_channel, g_channel, b_channel) ~color:(r,g,b) =
  Bigarray.Array2.fill r_channel r;
  Bigarray.Array2.fill g_channel g;
  Bigarray.Array2.fill b_channel b;
;;
let put_pixel_unsafe (_, r_channel, g_channel, b_channel) (r,g,b) =
  (fun x y ->
    r_channel.{x,y} <- r;
    g_channel.{x,y} <- g;
    b_channel.{x,y} <- b;
  )
let get_pixel_unsafe (_, r_channel, g_channel, b_channel) =
  (fun x y ->
    (r_channel.{x,y},
     g_channel.{x,y},
     b_channel.{x,y})
  )

we can overload these functions to make some bound checks:

let put_pixel img color x y =
  let _, r_channel,_,_ = img in
  let width = Bigarray.Array2.dim1 r_channel
  and height = Bigarray.Array2.dim2 r_channel in

  if (x < 0) || (x >= width) then invalid_arg "x out of bounds";
  if (y < 0) || (y >= height) then invalid_arg "y out of bounds";

  let r, g, b = color in
  if (r < 0) || (r > 255) then invalid_arg "red out of bounds";
  if (g < 0) || (g > 255) then invalid_arg "green out of bounds";
  if (b < 0) || (b > 255) then invalid_arg "blue out of bounds";

  put_pixel_unsafe img color x y;
;;

let get_pixel ~img ~pt:(x, y) =
  let _, r_channel,_,_ = img in
  let width = Bigarray.Array2.dim1 r_channel
  and height = Bigarray.Array2.dim2 r_channel in
  if (x < 0) || (x >= width) then invalid_arg "x out of bounds";
  if (y < 0) || (y >= height) then invalid_arg "y out of bounds";
  get_pixel_unsafe img x y;
;;

and a function to get the dimensions:

let get_dims ~img:(_, r_channel, _, _) =
  let width = Bigarray.Array2.dim1 r_channel
  and height = Bigarray.Array2.dim2 r_channel in
  (width, height)

Octave

In Octave, images are matrix. A grayscale W×H image is stored as a W×H matrix, and RGB W×H image is stored as a W×H×3 image. Possible levels depend on the class of the storage: if it is double, the intensity is a floating point double number between 0 and 1; if it is uint8, the intensity is from 0 to 255; if it is uint16, the intensity is between 0 and 65535.

im = zeros(W, H, 3, "uint8"); % create an RGB image of width W and height H
                              % and intensity from 0 to 255; black (all zeros)
im(:,:,1) = 255;              % set R to 255
im(:,:,2) = 100;              % set G to 100
im(:,:,3) = 155;              % set B to 155
im(floor(W/2), floor(H/2), :) = 0;  % pixel in the center made black
disp(im(floor(W/3), floor(H/3), :)) % display intensities of the pixel
                                    % at W/3, H/3
p = im(40,40,:); % or just store it in the vector p, so that
                 % p(1) is R, p(2) G and p(3) is B

We can hide this in helper functions like:

function im = create_rgb_image(w, h)
  im = zeros(w, h, 3, "uint8");
endfunction

function set_background(im, colorvector)
  im(:,:,1) = colorvector(1);
  im(:,:,2) = colorvector(2);
  im(:,:,3) = colorvector(3);
endfunction

function set_pixel(im, coord, colorvector)
  im(coord(1), coord(2), 1) = colorvector(1);
  im(coord(1), coord(2), 2) = colorvector(2);
  im(coord(1), coord(2), 3) = colorvector(3);
endfunction

function [r, g, b] = get_pixel(im, coord)
  r = im(coord(1), coord(2), 1)
  g = im(coord(1), coord(2), 2)
  b = im(coord(1), coord(2), 3)
endfunction

The only thing to note is that indexing start from 1.

%example
im = create_rgb_image(200,200);
for x = 1:128
   im = set_pixel(im, [x, x], [200, 50, 220]);
endfor

% it seems like saveimage wants double class on [0,1]
saveimage("image.ppm", double(im)./256, "ppm");

OxygenBasic

'GENERIC BITMAP

type pixel byte r,g,b

'===========
class BitMap
'===========

% sp   sizeof(pixel)
sys    wx,wy,px,py
string buf
sys    pb
method Constructor(sys x=640,y=480) { wx=x : wy=y : buf=nuls x*y*sp : pb=strptr buf}
method Destructor()                 {buf="" : wx=0 : wy=0 : pb=0}
method GetPixel(sys x,y,pixel*p)    {copy @p,pb+(y*wx+x)*sp,sp}
method SetPixel(sys x,y,pixel*p)    {copy pb+(y*wx+x)*sp,@p,sp}
'
method Fill(pixel*p)
  sys i, e=wx*wy*sp+pb-1
  for i=pb to e step sp {copy i,@p,sp}
end method

end class

pixel p,q

new BitMap m(400,400) 'width, height in pixels

p<=100,120,140 'red,green,blue

m.fill p

m.getPixel 200,100,q
print "" q.r "," q.g "," q.b 'result 100,120,140
q<=10,20,40
m.setPixel 200,100,q
m.getPixel 200,100,p
print "" p.r "," p.g "," p.b 'result 10,20,40


del m

Oz

We first create a 2D array data type as a functor in a file "Array2D.oz":

functor
export
   New
   Get
   Set
   Transform
define
   fun {New Width Height Init}
      C = {Array.new 1 Height unit}
   in
      for Row in 1..Height do
	 C.Row := {Array.new 1 Width Init}
      end

      array2d(width:Width
	      height:Height
	      contents:C)
   end

   fun {Get array2d(contents:C ...) X Y}
      C.Y.X
   end

   proc {Set array2d(contents:C ...) X Y Val}
      C.Y.X := Val
   end

   proc {Transform array2d(contents:C width:W height:H ...) Fun}
      for Y in 1..H do
	 for X in 1..W do
	    C.Y.X := {Fun C.Y.X}
	 end
      end
   end

   %% omitted: Clone, Map, Fold, ForAll
end

Based on this, we create a functor "Bitmap.oz":

%% For real task prefer QTk's images:
%% http://www.mozart-oz.org/home/doc/mozart-stdlib/wp/qtk/html/node38.html

functor
import
   Array2D
export
   New
   Fill
   GetPixel
   SetPixel
define
   Black = color(0x00 0x00 0x00)
   
   fun {New Width Height}
      bitmap( {Array2D.new Width Height Black} )
   end

   proc {Fill bitmap(Arr) Color}
      {Array2D.transform Arr fun {$ _} Color end}
   end
   
   fun {GetPixel bitmap(Arr) X Y}
      {Array2D.get Arr X Y}
   end
   
   proc {SetPixel bitmap(Arr) X Y Color}
      {Array2D.set Arr X Y Color}
   end

   %% Omitted: MaxValue, ForAllPixels, Transform
end

Some functions that are used in other tasks were omitted. See here for the complete module definitions: Basic bitmap storage/Oz

Pascal

Interface
uses  crt,   { GetDir }
      graph; { function GetPixel }

type { integer numbers }
  { from unit bitmaps XPERT software production Tamer Fakhoury }
  _bit     = $00000000..$00000001; {number 1 bit   without sign = (0..1) }
  _byte    = $00000000..$000000FF; {number 1 byte  without sign = (0..255)}
  _word    = $00000000..$0000FFFF; {number 2 bytes without sign = (0..65 535)}
  _dWord   = $00000000..$7FFFFFFF; {number 4 bytes without sign = (0..4 294 967 296)}
  _longInt = $80000000..$7FFFFFFF; {number 4 bytes with sign
                                    = (-2 147 483 648..2 147 483 648}

  TbmpFileHeader =
  record
    ID: _word;             { Must be 'BM' =19778=$424D for windows }
    FileSize: _dWord;      { Size of this file in bytes }
    Reserved: _dWord;      { ??? }
    bmpDataOffset: _dword; { = 54 = $36 from begining of file to begining of bmp data }
  end;

  TbmpInfoHeader =
  record
    InfoHeaderSize: _dword;      { Size of Info header
                                   = 28h = 40 (decimal)
                                   for windows }
    Width,
    Height: _longInt;    { Width and Height of image in pixels }
    Planes,              { number of planes of bitmap }
    BitsPerPixel: _word; { Bits can be 1, 4, 8, 24 or 32 }
    Compression,
    bmpDataSize: _dword;    { in bytes rounded to the next 4 byte boundary }
    XPixPerMeter,           { horizontal resolution in pixels }
    YPixPerMeter: _longInt; { vertical }
    NumbColorsUsed,
    NumbImportantColors: _dword;   {= NumbColorUsed}
  end; { TbmpHeader = Record ... }

  T32Color =
  record { 4 byte = 32 bit }
    Blue:  byte;
    Green: byte;
    Red:   byte;
    Alfa:  byte
  end;

var directory,
    bmpFileName:    string;
    bmpFile:        file; { untyped file }
    bmpFileHeader:  TbmpFileHeader;
    bmpInfoHeader:  TbmpInfoHeader;
    color32:        T32Color;
    RowSizeInBytes: integer;
    BytesPerPixel:  integer;

const defaultBmpFileName = 'test';
      DefaultDirectory   = 'c:\bp\';
      DefaultExtension   = '.bmp';
      bmpFileHeaderSize  = 14;
      { compression specyfication }
      bi_RGB             = 0;  { compression }
      bi_RLE8            = 1;
      bi_RLE4            = 2;
      bi_BITFIELDS       = 3;

      bmp_OK          = 0;
      bmp_NotBMP      = 1;
      bmp_OpenError   = 2;
      bmp_ReadError   = 3;

Procedure CreateBmpFile32(directory: string; FileName: string;
                           iWidth, iHeight: _LongInt);

{************************************************}
Implementation  {-----------------------------}
{************************************************}

Procedure CreateBmpFile32(directory: string; FileName: string;
                           iWidth, iHeight: _LongInt);
  var
    x, y: integer;
  begin
    if directory = '' then
      GetDir(0, directory);
    if FileName = '' then
      FileName: = DefaultBmpFileName;
    { create a new file on a disk in a given directory with given name }
    Assign(bmpFile, directory + FileName + DefaultExtension);
    ReWrite(bmpFile, 1);

    { fill the headers }
    with bmpInfoHeader, bmpFileHeader do
    begin
      ID := 19778;
      InfoheaderSize := 40;
      width := iWidth;
      height := iHeight;
      BitsPerPixel := 32;
      BytesPerPixel := BitsPerPixel div 8;
      reserved := 0;
      bmpDataOffset := InfoHeaderSize + bmpFileHeaderSize;
      planes := 1;
      compression := bi_RGB;
      XPixPerMeter := 0;
      YPixPerMeter := 0;
      NumbColorsUsed := 0;
      NumbImportantColors := 0;

      RowSizeInBytes := (Width * BytesPerPixel); { only for >=8 bits per pixel }
      bmpDataSize := height * RowSizeinBytes;
      FileSize := InfoHeaderSize + bmpFileHeaderSize + bmpDataSize;

      { copy headers to disk file }
      BlockWrite(bmpFile, bmpFileHeader, bmpFileHeaderSize);
      BlockWrite(bmpFile, bmpInfoHeader, infoHeaderSize);

      { fill the pixel data area }
      for y := (height - 1) downto 0  do
      begin
	for x := 0 to (width - 1) do
	begin { Pixel(x,y) }
	  color32.Blue  := 255;
	  color32.Green := 0;
	  color32.Red   := 0;
	  color32.Alfa  := 0;
	  BlockWrite(bmpFile, color32, 4);
	end; { for x ... }
      end; { for y ... }
      Close(bmpFile);
    end; { with bmpInfoHeader, bmpFileHeader }
   end; { procedure }

Perl

Library: Imlib2
#! /usr/bin/perl

use strict;

use Image::Imlib2;

# create the "canvas"
my $img = Image::Imlib2->new(200,200);

# fill with a plain RGB(A) color
$img->set_color(255, 0, 0, 255);
$img->fill_rectangle(0,0, 200, 200);

# set a pixel to green (at 40,40)
$img->set_color(0, 255, 0, 255);
$img->draw_point(40,40);

# "get" pixel rgb(a)
my ($red, $green, $blue, $alpha) = $img->query_pixel(40,40);
undef $img;

# another way of creating a canvas with a bg colour (or from
# an existing "raw" data)
my $col = pack("CCCC", 255, 255, 0, 0); # a, r, g, b
my $img = Image::Imlib2->new_using_data(200, 200, $col x (200 * 200));

exit 0;

Phix

Copy of Euphoria

with javascript_semantics
-- Some colour constants:
constant black = #000000,
--       blue  = #0000FF,
--       green = #00FF00,
--       red   = #FF0000,
         white = #FFFFFF
 
-- Create new image filled with some colour
function new_image(integer width, integer height, integer fill_colour=black)
    return repeat(repeat(fill_colour,height),width)
end function
 
-- Usage example:
sequence image = new_image(800,600)
 
-- Set pixel color:
image[400][300] = white
 
-- Get pixel color
integer colour = image[400][300] -- Now colour is #FFFFFF

PHP

class Bitmap {
  public $data;
  public $w;
  public $h;
  public function __construct($w = 16, $h = 16){
    $white = array_fill(0, $w, array(255,255,255));
    $this->data = array_fill(0, $h, $white);
    $this->w = $w;
    $this->h = $h;
  }
  //Fills a rectangle, or the whole image with black by default
  public function fill($x = 0, $y = 0, $w = null, $h = null, $color = array(0,0,0)){
    if (is_null($w)) $w = $this->w;
    if (is_null($h)) $h = $this->h;
    $w += $x;
    $h += $y;
    for ($i = $y; $i < $h; $i++){
      for ($j = $x; $j < $w; $j++){
        $this->setPixel($j, $i, $color);
      }
    }
  }
  public function setPixel($x, $y, $color = array(0,0,0)){
    if ($x >= $this->w) return false;
    if ($x < 0) return false;
    if ($y >= $this->h) return false;
    if ($y < 0) return false;
    $this->data[$y][$x] = $color;
  }
  public function getPixel($x, $y){
    return $this->data[$y][$x];
  }
}

$b = new Bitmap(16,16);
$b->fill();
$b->fill(2, 2, 18, 18, array(240,240,240));
$b->setPixel(0, 15, array(255,0,0));
print_r($b->getPixel(3,3)); //(240,240,240)

PicoLisp

For time critical applications this would be done with inline-C in PicoLisp, but especially for small bitmaps the following makes sense.

# Create an empty image of 120 x 90 pixels
(setq *Ppm (make (do 90 (link (need 120)))))

# Fill an image with a given color
(de ppmFill (Ppm R G B)
   (for Y Ppm
      (map
         '((X) (set X (list R G B)))
         Y ) ) )

# Set pixel with a color
(de ppmSetPixel (Ppm X Y R G B)
   (set (nth Ppm Y X) (list R G B)) )

# Get the color of a pixel
(de ppmGetPixel (Ppm X Y)
   (get Ppm Y X) )

PL/I

/* Declaration for an image, suitable for BMP files. */
declare image(0:500, 0:500) bit (24) aligned;

image = '000000000000000011111111'b;
   /* Sets the entire image to red. */

image(10,40) = '111111110000000000000000'b;
   /* Sets one pixel to blue. */

declare color bit (24) aligned;
color = image(20,50); /* Obtain the color of a pixel */



/* To allocate an image of size (x,y) */
allocate_image: procedure (image, x, y);
   declare image (*, *) controlled bit (24) aligned;
   declare (x, y) fixed binary (31);

   allocate image (0:x, 0:y);
end allocate_image;

/* To use the above procedure, it's necessary to define   */
/* the image in the calling program thus, for BMP images: */

declare image(*,*) controlled bit (24) aligned;

Processing

PGraphics bitmap = createGraphics(100,100); // Create the bitmap
bitmap.beginDraw();
bitmap.background(255, 0, 0); // Fill bitmap with red rgb color
bitmap.endDraw();
image(bitmap, 0, 0); // Place bitmap on screen.
color b = color(0, 0, 255); // Define a blue rgb color
set(50, 50, b); // Set blue colored pixel in the middle of the screen
color c = get(50, 50); // Get the color of same pixel
if(b == c) print("Color changed correctly"); // Verify

Prolog

:- module(bitmap, [
	new_bitmap/3,
	fill_bitmap/3,
	get_pixel0/3,
	set_pixel0/4 ]).

:- use_module(library(lists)).

%-----------------------------------------------------------------------------%
% Convenience Predicates
replicate(Term,Times,L):-
	length(L,Times),
	maplist(=(Term),L).

replace0(N,OL,E,NL):-
	nth0(N,OL,_,TL),
	nth0(N,NL,E,TL).
%-----------------------------------------------------------------------------%
% Bitmap Utilities
%
% The Bitmap structure is a list with pixels kept in row major order:
% [dimensions-[X,Y],pixels-[[n11,n12...],[n21,n22...]]]

% In this code what exactly an RGB value is doesn't matter however 
% in other bitmap tasks it is assumed to be a list [R,G,B] where
% each is an int between 0 and 255, in code:
rgb_pixel(RGB):-
	length(RGB,3),
	maplist(integer,RGB),
	maplist(between(0,255),RGB).

%new_bitmap(Bitmap,Dimensions,RGB)
new_bitmap([[X,Y],Pixels],[X,Y],RGB) :-
	replicate(RGB,X,Row),
	replicate(Row,Y,Pixels).
	
%fill_bitmap(New_Bitmap,Bitmap,RGB)
fill_bitmap(New_Bitmap,[[X,Y],_],RGB) :-
	new_bitmap(New_Bitmap,[X,Y],RGB).

%here get and set use 0 based indexing
%get_pixel0(Bitmap,Coordinates,RGB)
get_pixel0([[_DimX,_DimY],Pixels],[X,Y],RGB) :-
	nth0(Y,Pixels,Row),
	nth0(X,Row,RGB).

%set_pixel0(New Bitmap, Bitmap, Coordinates, RGB)
set_pixel0([[DimX,DimY],New_Pixels],[[DimX,DimY],Pixels],[X,Y],RGB) :-
	nth0(Y,Pixels,Row),
	replace0(X,Row,RGB,New_Row),
	replace0(Y,Pixels,New_Row,New_Pixels).

PureBasic

w=800 : h=600
CreateImage(1,w,h) 
;1 is internal id of image
StartDrawing(ImageOutput(1))
; fill with color red
Box(0,0,w,h,$ff)
; or using another (but slower) way in green
FillArea(0,0,-1,$ff00)
; a green Dot
Plot(10,10,$ff0000)
; check if we set it right (should be 255)
Debug Blue(Point(10,10))

Python

See Basic bitmap storage/Python

QBasic

Works with: QBasic version 1.1
SUB establecePixel (x AS INTEGER, y AS INTEGER, c AS INTEGER)
    PSET (x, y), cyan
END SUB

SUB rellenar (c AS INTEGER)
    SHARED w, h
    LINE (0, 0)-(w / 3, h / 3), red, BF
END SUB

SCREEN 13
w = 320: h = 200
CONST cyan = 3, red = 4

rellenar (12)
CALL establecePixel(10, 10, cyan)
LOCATE 12
PRINT "pixel 10,10 is "; POINT(10, 10)
PRINT "pixel 20,20 is "; POINT(20, 10)

R

Library: pixmap

R can write to most bitmap image formats by default (mostly for the purpose of saving graphs), however there is no built-in way of manipulating images. The pixmap package reads, writes and manipulates portable bitmap file types: PBM, PGM, PPM. See also, the image function, and the rimage and ReadImage packages, which use libjpeg to read JPEG and PNG files.

#  See the class definitions and constructors with, e.g. 
getClass("pixmapIndexed", package=pixmap)
pixmapIndexed

# Image with all one colour
plot(p1 <- pixmapIndexed(matrix(0, nrow=3, ncol=4), col="red"))

# Image with one pixel specified
cols <- rep("blue", 12); cols[7] <- "red"
plot(p2 <- pixmapIndexed(matrix(1:12, nrow=3, ncol=4), col=cols))

# Retrieve colour of a pixel
getcol <- function(pm, i, j)
{
   pmcol <- pm@col
   dim(pmcol) <- dim(pm@index)
   pmcol[i,j]   
}
getcol(p2, 3, 4)  #red

Racket

#lang racket

;; The racket/draw libraries provide imperative drawing functions.
;; http://docs.racket-lang.org/draw/index.html
(require racket/draw)
         
;; To create an image with width and height, use the make-bitmap
;; function.

;; For example, let's make a small image here:
(define bm (make-bitmap 640 480))

;; We use a drawing context handle, a "dc", to operate on the bitmap.
(define dc (send bm make-dc))

;; We can fill the bitmap with a color by using a combination of
;; setting the background, and clearing.
(send dc set-background (make-object color% 0 0 0)) ;; Color it black.
(send dc clear)

;; Let's set a few pixels to a greenish color with set-pixel:
(define aquamarine (send the-color-database find-color "aquamarine"))
(for ([i 480])
  (send dc set-pixel i i aquamarine))

;; We can get at the color of a bitmap pixel by using the get-pixel
;; method.  However, it may be faster to use get-argb-pixels if we
;; need a block of the pixels.  Let's use get-argb-pixels and look
;; at a row starting at (0, 42)
(define buffer (make-bytes (* 480 4)))  ;; alpha, red, green, blue
(send dc get-argb-pixels 0 42 480 1 buffer)

;; We can inspect the buffer
(bytes-ref buffer 0) ;;  and see that the first pixel's alpha is 255,
(bytes-ref buffer 1) ;;  and the red, green, and blue components are 0.
(bytes-ref buffer 2)
(bytes-ref buffer 3)

;; If we are using DrRacket, we can just print the bm as a toplevel expression
;; to view the final image:
bm

Raku

(formerly Perl 6)

class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
    has UInt ($.width, $.height);
    has Pixel @!data;

    method fill(Pixel $p) {
        @!data = $p.clone xx ($!width*$!height)
    }
    method pixel(
	$i where ^$!width,
	$j where ^$!height
	--> Pixel
    ) is rw { @!data[$i + $j * $!width] }

    method set-pixel ($i, $j, Pixel $p) {
	self.pixel($i, $j) = $p.clone;
    }
    method get-pixel ($i, $j) returns Pixel {
	self.pixel($i, $j);
    }
}

my Bitmap $b = Bitmap.new( width => 10, height => 10);

$b.fill( Pixel.new( R => 0, G => 0, B => 200) );

$b.set-pixel( 7, 5, Pixel.new( R => 100, G => 200, B => 0) );

say $b.perl;

Thanks to the rw trait on the pixel method, we don't actually need to define two separate methods, set-pixel and get-pixel, but that is an explicit requirement of the task. (Beware your presuppositions! In Raku, accessors only determine identity, not use. In particular, identity is considered orthogonal to lvalue/rvalue context.)

RapidQ

QCanvas is an empty image on which you can draw. QForm is the main window of the application. The commands to draw on the canvas are in the procedure PaintCanvas, which is executed each time the canvas need to be (re)painted.

DECLARE SUB PaintCanvas

CREATE form AS QForm
    Width  = 640
    Height = 480
    CREATE canvas AS QCanvas
        Height  = form.ClientHeight
	Width   = form.ClientWidth
	OnPaint = PaintCanvas
    END CREATE
END CREATE

SUB PaintCanvas
    ' Fill background
    canvas.FillRect(0, 0, canvas.Width, canvas.Height, &H301000)

    ' Draw a pixel
    canvas.Pset(300, 200, &H00ddff)

    ' Read pixel color
    PRINT canvas.Pixel(300, 200)
END SUB

form.ShowModal

REXX

version 1

The REXX language has no need to declare the size of (stemmed) arrays.

Indeed, there is no way to declare array sizes   (or any variable, for that matter).

The image (raster) created was also written to a file   (image.PPM)   to show verification of the image.

/*REXX program demonstrates how to process/display                     */
/*                                a simple  RGB  raster graphics image.*/
red   = 'ff 00 00'x             /*a method to define a   red   value.  */
blue  = '00 00 ff'x             /*'    '    '    '   '   blue    '     */
pixel=''                        /*define entire  pixel. array to nulls.*/
outFN = 'image'                 /*the filename of the output image PPM */
sWidth = 500; sHeight= 500      /*the screen width and height in pixels*/
Call RGBfill red                /*set the entire   image   to red.     */
x=10; y=40                      /*set pixel's coördinates.             */
Call RGBset x,y,blue            /*set a pixel (at  10,40)  to blue.    */
color = RGBget(x,y)             /*get the color of a pixel.            */
hexV  = c2x(color)              /*get hex    value of pixel's color.   */
binV  = x2b(hexV)               /* "  binary   "    "    "      "      */
bin3V = left(binV,8) substr(binV,9,8) right(binV,8)
hex3V = left(hexV,2) substr(hexV,3,2) right(hexV,2)
xy= '('||x','y')'               /*create a handy-dandy literal for SAY.*/
Say xy ' pixel in binary: ' binV   /*show the binary value of  20,50   */
Say xy ' pixel in binary: ' bin3V  /*show again,but with spaces.       */
Say                                /*show a blank between bin & hex.   */
Say xy ' pixel in hex:    ' hexV   /*show again,but in hexadecimal.    */
Say xy ' pixel in hex:    ' hex3V  /*show again,but with spaces.       */
Call PPMwrite outFN,sWidth,sHeight /*create a PPM (output) file        */  
    /* ?¦¦¦¦¦¦¦¦ not part of this task.*/
Say                                      /*show a blank.               */
Say 'The file ' outFN'.PPM was created.' /*inform user                 */
Exit                             /*stick a fork in it, we're all done. */
/*---------------------------------------------------------------------*/
RGBfill: pixel.=arg(1);   Return             /*fill image with a color.*/
RGBget:  Parse arg px,py; Return pixel.px.py /*get a pixel's color.    */
RGBset:  Parse arg px,py,psep; pixel.px.py=psep; Return /*set a pixel  */
/*---------------------------------------------------------------------*/
PPMwrite: Parse arg oFN,width,height
  oFID= oFN'.PPM'               /* fileID                              */
  sep='9'x;                     /* separator                           */
  maxcol=255                    /* max color value.                    */
  Call charout oFID,,1          /*set the position of the file's output*/
  Call charout oFID,'P6'width||sep||height||sep||maxcol||sep /* header */
  Do i=1 To width
    Do j=1 To height;
      Call charout oFID,pixel.i.j
      End
    End
  Call charout oFID           /* close the output file just to be safe */
  Return
output:
(10,40)  pixel in binary:  000000000000000011111111
(10,40)  pixel in binary:  00000000 00000000 11111111

(10,40)  pixel in hex:     0000FF
(10,40)  pixel in hex:     00 00 FF

The file  image.PPM  was created.

version 2

This program actually creates a BMP file

/* REXX ***************************************************************
* Draw a picture from pixels
* 16.06.2014 Walter Pachl
**********************************************************************/
oid='pic.bmp'; 'erase' oid

blue ='FF0000'x;
green='00FF00'x;
red  ='0000FF'x;
white='ffffff'x;
black='000000'x;

w=600                        /* width  */
h=300                        /* height */
w3=w*3

bfType         ='BM'
bfSize         ='46000000'x
bfReserved     ='00000000'x
bfOffBits      ='36000000'x
biSize         ='28000000'x
biWidth        =lend(w)
biHeight       =lend(h)
biPlanes       ='0100'x
biBitCount     ='1800'x
biCompression  ='00000000'x
biSizeImage    ='10000000'x
biXPelsPerMeter='00000000'x
biYPelsPerMeter='00000000'x
biClrUsed      ='00000000'x
biClrImportant ='00000000'x

s=bfType||,
  bfSize||,
  bfReserved||,
  bfOffBits||,
  biSize||,
  biWidth||,
  biHeight||,
  biPlanes||,
  biBitCount||,
  biCompression||,
  biSizeImage||,
  biXPelsPerMeter||,
  biYPelsPerMeter||,
  biClrUsed||,
  biClrImportant

pic=copies(red,w*h)             /* fill the rectangle with color red */
Call rect 100,100,180,180,green /* draw a green rectangle            */
Call rect 100,100,160,160,blue  /* and a blue rectangle within that  */
Call dot 120,120,white          /* one pixel is hardly visible       */
Do x=98 To 102                  /* draw a square of 25 pixels        */
  Do y=98 To 102
    Call dot x,y,white
    End
  End
Call charout oid,s||pic         /* write the picture to file         */
dmy=col(97,98)
dmy=col(98,98)
Exit

lend: Procedure
/**********************************************************************
* compute the representation of a number (little endian)
**********************************************************************/
Parse Arg n
res=reverse(d2c(n,4))
rev=reverse(res)
say 'lend:' arg(1) '->' c2x(res) '=>' c2d(rev)
Return res

rect: Procedure Expose pic w h w3
/**********************************************************************
* Fill a rectangle with center at x,y and width/height = wr/hr
**********************************************************************/
Parse Arg x,y,wr,hr,color
Say x y wr hr c2x(color)
i=w3*(y-1)+3*(x-1)+1               /* Pixel position of center       */
ia=max(w3*(y-1)+1,i-3*(wr%2))      /* position of left border        */
ib=min(i+3*wr%2,w3*y)              /* position of right border       */
lc=ib-ia                           /* length of horizontal line      */
If lc>=0 Then Do
  os=copies(color,lc%3)            /* the horizontal line            */
  Do hi=-hr%2 to hr%2              /* loop from lower to upper border*/
    i=trunc(ia+w3*hi)              /* position of line's left border */
    If i>1 Then Do
      pic=overlay(os,pic,i)        /* put the line into the picture  */
      j=i%w3
      End
    End
  End
Return

dot: Procedure Expose pic w h w3
/**********************************************************************
* Put a dot at position x/y into the picture
**********************************************************************/
Parse Arg x,y,color
i=w3*(y-1)+3*(x-1)
pic=overlay(color,pic,i+1)
Return

col: Procedure Expose pic w h w3
/**********************************************************************
* get the color at position x/y
**********************************************************************/
Parse Arg x,y,color
i=w3*(y-1)+3*(x-1)
say 'color at pixel' x'/'y'='c2x(substr(pic,i+1,3))
Return c2x(substr(pic,i+1,3))
Output:
lend: 600 -> 58020000 => 600
lend: 300 -> 2C010000 => 300
100 100 180 180 00FF00
100 100 160 160 FF0000
color at pixel 97/98=FF0000
color at pixel 98/98=FFFFFF

and have a look at the file pic.bmp created by this program

Ruby

I haven't been able to find any kind of package for manipulating bitmap images, so let's roll one

class RGBColour
  def initialize(red, green, blue)
    unless red.between?(0,255) and green.between?(0,255) and blue.between?(0,255)
      raise ArgumentError, "invalid RGB parameters: #{[red, green, blue].inspect}"
    end
    @red, @green, @blue = red, green, blue
  end
  attr_reader :red, :green, :blue
  alias_method :r, :red
  alias_method :g, :green
  alias_method :b, :blue

  RED   = RGBColour.new(255,0,0)
  GREEN = RGBColour.new(0,255,0)
  BLUE  = RGBColour.new(0,0,255)
  BLACK = RGBColour.new(0,0,0)
  WHITE = RGBColour.new(255,255,255)
end

class Pixmap
  def initialize(width, height)
    @width = width
    @height = height
    @data = fill(RGBColour::WHITE)
  end
  attr_reader :width, :height

  def fill(colour)
    @data = Array.new(@width) {Array.new(@height, colour)}
  end

  def validate_pixel(x,y)
    unless x.between?(0, @width-1) and y.between?(0, @height-1)
      raise ArgumentError, "requested pixel (#{x}, #{y}) is outside dimensions of this bitmap"
    end
  end

  def [](x,y)
    validate_pixel(x,y)
    @data[x][y]
  end
  alias_method :get_pixel, :[]

  def []=(x,y,colour)
    validate_pixel(x,y)
    @data[x][y] = colour
  end
  alias_method :set_pixel, :[]=
end

Rust

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Rgb {
    pub r: u8,
    pub g: u8,
    pub b: u8,
}

impl Rgb {
    pub fn new(r: u8, g: u8, b: u8) -> Self {
        Rgb { r, g, b }
    }

    pub const BLACK: Rgb = Rgb { r: 0, g: 0, b: 0 };
    pub const RED: Rgb = Rgb { r: 255, g: 0, b: 0 };
    pub const GREEN: Rgb = Rgb { r: 0, g: 255, b: 0 };
    pub const BLUE: Rgb = Rgb { r: 0, g: 0, b: 255 };
}

#[derive(Clone, Debug)]
pub struct Image {
    width: usize,
    height: usize,
    pixels: Vec<Rgb>,
}

impl Image {
    pub fn new(width: usize, height: usize) -> Self {
        Image {
            width,
            height,
            pixels: vec![Rgb::BLACK; width * height],
        }
    }
    
    pub fn width(&self) -> usize {
        self.width
    }
    
    pub fn height(&self) -> usize {
        self.height
    }

    pub fn fill(&mut self, color: Rgb) {
        for pixel in &mut self.pixels {
            *pixel = color;
        }
    }

    pub fn get(&self, row: usize, col: usize) -> Option<&Rgb> {
        if row >= self.width {
            return None;
        }
        self.pixels.get(row * self.width + col)
    }

    pub fn get_mut(&mut self, row: usize, col: usize) -> Option<&mut Rgb> {
        if row >= self.width {
            return None;
        }
        self.pixels.get_mut(row * self.width + col)
    }
}

fn main() {
    let mut image = Image::new(16, 9);
    assert_eq!(Some(&Rgb::BLACK), image.get(3, 4));
    assert!(image.get(22, 3).is_none());

    image.fill(Rgb::RED);
    assert_eq!(Some(&Rgb::RED), image.get(3, 4));

    if let Some(pixel) = image.get_mut(3, 4) {
        *pixel = Rgb::GREEN;
    }
    assert_eq!(Some(&Rgb::GREEN), image.get(3, 4));

    if let Some(pixel) = image.get_mut(3, 4) {
        pixel.g -= 100;
        pixel.b = 20;
    }
    assert_eq!(Some(&Rgb::new(0, 155, 20)), image.get(3, 4));
}

Scala

Java translation

Translation of: Java
import java.awt.image.BufferedImage
import java.awt.Color

class RgbBitmap(val width:Int, val height:Int) {
   val image=new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR)

   def fill(c:Color)={
      val g=image.getGraphics()
      g.setColor(c)
      g.fillRect(0, 0, width, height)
   }

   def setPixel(x:Int, y:Int, c:Color)=image.setRGB(x, y, c.getRGB())
   def getPixel(x:Int, y:Int)=new Color(image.getRGB(x, y))
}

Usage:

val img=new RgbBitmap(50, 50);
img.fill(Color.CYAN)
img.setPixel(5, 5, Color.BLUE)

assert(img.getPixel(1,1)==Color.CYAN)
assert(img.getPixel(5,5)==Color.BLUE)
assert(img.width==50)
assert(img.height==50)

Scala idiom

A more Scalesque version could be with the use of its idiom:

Output:

Best experienced in your browser with Scastie (remote JVM).

import java.awt.image.BufferedImage
import java.awt.Color

object RgbBitmap extends App {
  class RgbBitmap(val dim: (Int, Int)) {
    def width = dim._1
    def height = dim._2

    private val image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR)

    def apply(x: Int, y: Int) = new Color(image.getRGB(x, y))

    def update(x: Int, y: Int, c: Color) = image.setRGB(x, y, c.getRGB)

    def fill(c: Color) = {
      val g = image.getGraphics
      g.setColor(c)
      g.fillRect(0, 0, width, height)
    }
  }

  object RgbBitmap {
    def apply(width: Int, height: Int) = new RgbBitmap(width, height)
  }


  /** Even Javanese style testing is still possible.
    */
  private val img0 = new RgbBitmap(50, 60) { // Wrappers to enable adhoc Javanese style
    def getPixel(x: Int, y: Int) = this(x, y)
    def setPixel(x: Int, y: Int, c: Color) = this(x, y) = c
  }

  img0.fill(Color.CYAN)
  img0.setPixel(5, 6, Color.BLUE)
  // Testing in Java style
  assert(img0.getPixel(0, 1) == Color.CYAN)
  assert(img0.getPixel(5, 6) == Color.BLUE)
  assert(img0.width == 50)
  assert(img0.height == 60)
  println("Tests successfully completed with no errors found.")
}

Scheme

Works with: Scheme version RRS

Definitions of list procedures:

(define (make-list length object)
  (if (= length 0)
      (list)
      (cons object (make-list (- length 1) object))))

(define (list-fill! list object)
  (if (not (null? list))
      (begin (set-car! list object) (list-fill! (cdr list) object))))

(define (list-set! list element object)
  (if (= element 1)
      (set-car! list object)
      (list-set! (cdr list) (- element 1) object)))

(define (list-get list element)
  (if (= element 1)
      (car list)
      (list-get (cdr list) (- element 1))))

Definitions of image procedures:

(define (make-image columns rows)
  (if (= rows 0)
      (list)
      (cons (make-list columns (list)) (make-image columns (- rows 1)))))

(define (image-fill! image colour)
  (if (not (null? image))
      (begin (list-fill! (car image) colour) (image-fill! (cdr image) colour))))

(define (image-set! image column row colour)
  (list-set! (list-get image row) column colour))

(define (image-get image column row)
  (list-get (list-get image row) column))

Definitions of some colours:

(define *black* (list   0   0   0))
(define *white* (list 255 255 255))
(define *red*   (list 255   0   0))
(define *green* (list   0 255   0))
(define *blue*  (list   0   0 255))

This creates a small image with a black background and a single blue pixel:

(define image (make-image 3 2))
(image-fill! image *black*)
(image-set! image 2 1 *blue*)
(display image)
(newline)
Output:
(((0 0 0) (0 0 255) (0 0 0)) ((0 0 0) (0 0 0) (0 0 0)))

Seed7

The types and functions requested are predefined in the libraries graph.s7i and draw.s7i:

  • The type to handle an RGB raster graphics image is PRIMITIVE_WINDOW.
  • The function to create an image is newPixmap.
  • An imaged can be filled with a color with clear.
  • A given pixel can be set with point.
  • The color of a pixel can be retrieved with getPixelColor.
$ include "seed7_05.s7i";
  include "draw.s7i";

const proc: main is func
  local
    var PRIMITIVE_WINDOW: myPixmap is PRIMITIVE_WINDOW.value;
    var color: myColor is black;
  begin
    myPixmap := newPixmap(300, 200);
    clear(myPixmap, light_green);
    point(myPixmap, 20, 30, color(256, 512, 768));
    myColor := getPixelColor(myPixmap, 20, 30);
    writeln(myColor.redLight <& " " <& myColor.greenLight <& " " <& myColor.blueLight);
  end func;

SequenceL

RGB ::= (R: int(0), G: int(0), B: int(0));

newBitmap: int * int -> RGB(2);
newBitmap(width, height)[y, x] :=
	 (R: 0, G: 0, B: 0)
	 foreach y within 1 ... height, 
	 		 x within 1 ... width;

fill: RGB(2) * RGB -> RGB(2);
fill(bitmap(2), color)[y, x] :=
	color
	foreach y within 1 ... size(bitmap),
			x within 1 ... size(bitmap[y]);

setColorAt: RGB(2) * int * int * RGB -> RGB(2);
setColorAt(bitmap(2), x, y, color)[Y, X] :=
		color when Y = y and X = x
	else
		bitmap[Y, X];
	
getColorAt: RGB(2) * int * int -> RGB;	
getColorAt(bitmap(2), x, y) := bitmap[y, x]; 

lightGreen := (R: 51, G: 255, B: 51);
lightRed := (R: 255, G: 51, B: 51);

main(args(2)) :=
	let
		width := 1920;
		height := 1200;
		
		cleanImage := newBitmap(width, height);
		
		filledGreen := fill(cleanImage, lightGreen);
		
		redCenter := setColorAt(filledGreen, width / 2, height / 2, lightRed);
	in
		getColorAt(redCenter, width / 2, height / 2);
Output:
cmd:> main.exe
(B:51,G:51,R:255)

Smalltalk

Works with: Smalltalk/X
|img1 img2|
"a depth24 RGB image"
img1 := Image width:100 height:200 depth:24.
img1 fillRectangle:(0@0 corner:100@100) with:Color red.
img1 fillRectangle:(0@100 corner:100@100) with:(Color rgbValue: 16rFF00FF).
img1 colorAt:(10 @ 10) put:(Color green).
img1 saveOn:'sampleFile.png'.

img1 displayOn:Transcript window graphicsContext.
Transcript showCR:(img1 colorAt:(100 @ 10) ).

"a depth8 palette image"
img2 := Image width:100 height:200 depth:8.
img2 colorMap:{ Color black. Color red . Color green }. 
img2 fillRectangle:(0@0 corner:100@100) with:Color red.
img2 fillRectangle:(0@100 corner:100@100) with: 16r02.
img2 colorAt:(10 @ 10) put:(Color green).
img2 saveOn:'sampleFile.gif'.

img2 displayOn:Transcript window graphicsContext.
Transcript showCR:(img2 colorAt:(100 @ 10) ).

Tcl

Library: Tk
package require Tcl 8.5
package require Tk
namespace path ::tcl::mathfunc ;# for [max] function

proc newImage {width height} {
    return [image create photo -width $width -height $height]
}
proc fill {image colour} {
    $image put $colour -to 0 0 [$image cget -width] [$image cget -height]
}
proc setPixel {image colour point} {
    lassign $point x y
    $image put $colour -to [max 0 $x] [max 0 $y]
}
proc getPixel {image point} {
    lassign $point x y
    # [$img get] returns a list: {r g b}; this proc should return a colour value
    format {#%02x%02x%02x} {*}[$image get $x $y]
}

# create the image and display it
set img [newImage 150 150]
label .l -image $img
pack .l

fill $img red

setPixel $img green {40 40}

set rbg [getPixel $img {40 40}]

TI-89 BASIC

TI-89 BASIC does not have user-defined data structures. The Rosetta Code tasks which use this image type have instead been implemented using the TI-89's graph screen.

UNIX Shell

Works with: ksh93
typeset -T RGBColor_t=(
    integer r g b
    function to_s {
        printf "%d %d %d" ${_.r} ${_.g} ${_.b}
    }
    function white   { print "255 255 255"; }
    function black   { print "0 0 0"; }
    function red     { print "255 0 0"; }
    function green   { print "0 255 0"; }
    function blue    { print "0 0 255"; }
    function yellow  { print "255 255 0"; }
    function magenta { print "255 0 255"; }
    function cyan    { print "0 255 255"; }
)

typeset -T Bitmap_t=(
    integer height
    integer width
    typeset -a data

    function fill {
        typeset color=$1
        if [[ -z ${color:+set} ]]; then
            print -u2 "error: no fill color specified"
            return 1
        fi
        integer x y
        for ((y=0; y<_.height; y++)); do
            for ((x=0; x<_.width; x++)); do
                _.data[y][x]="$color"
            done
        done
    }

    function setpixel {
        integer x=$1 y=$2 
        typeset color=$3
        _.data[y][x]=$color
    }

    function getpixel {
        integer x=$1 y=$2 
        print "${_.data[y][x]}"
    }

    function to_s {
        typeset ppm=""
        ppm+="P3"$'\n'
        ppm+="${_.width} ${_.height}"$'\n'
        ppm+="255"$'\n'
        typeset sep
        for ((y=0; y<_.height; y++)); do
            sep=""
            for ((x=0; x<_.width; x++)); do
                ppm+="$sep${_.data[y][x]}"
                sep=" "
            done
            ppm+=$'\n'
        done
        print -- "$ppm"
    }
)

RGBColor_t color
Bitmap_t b=( width=3  height=2 )
b.fill "$(color.white)"
b.setpixel 0 0 "$(color.red)"
b.setpixel 1 0 "$(color.green)"
b.setpixel 2 0 "$(color.blue)"
b.setpixel 0 1 "$(color.yellow)"
b.setpixel 1 1 "$(color.white)"
b.setpixel 2 1 "$(color.black)"
echo "$(b.getpixel 0 0)"
b.to_s
Output:
255 0 0
P3
3 2
255
255 0 0 0 255 0 0 0 255
255 255 0 255 255 255 0 0 0

Vedit macro language

An edit buffer is used to store pixel data. In order to allow unlimited image size, a temporary file (here pixel.data) can be assosicated to the buffer. You could directly open the image file you are creating (as in the task Dragon_curve, but here we first create just the plain pixel data so that the required image file format can be decided later.

#11 = 400		// Width of the image
#12 = 300		// Height of the image

// Create an empty RGB image and fill it with black color
//
File_Open("|(VEDIT_TEMP)\pixel.data", OVERWRITE+NOEVENT)
BOF
Del_Char(ALL)
#10 = Buf_Num
Repeat(#11 * #12) {
    Ins_Char(0, COUNT, 3)
}

// Fill the image with dark blue color
//
#5 = 0				// Red
#6 = 0				// Green
#7 = 64				// Blue
Call("FILL_IMAGE")

// Draw one pixel in orange color
//
#1 = 100			// x
#2 = 50				// y
#5 = 255 #6 = 128 #7 = 0	// Orange color
Call("DRAW_PIXEL")

// Get the color of a pixel
//
#1 = 10
#2 = 3
Call("GET_COLOR")

Buf_Switch(#10) Buf_Quit(OK)
Return

/////////////////////////////////////////////////////////////////////
//
//  Fill image with given color: #5 = Red, #6 = Green, #7 = Blue
//
:FILL_IMAGE:
BOF
Repeat (File_Size/3) {
    IC(#5,OVERWRITE) IC(#6,OVERWRITE) IC(#7,OVERWRITE)
}
Return

/////////////////////////////////////////////////////////////////////
//
//  Daw a pixel. #1 = x, #2 = y
//
:DRAW_PIXEL:
Goto_Pos((#1 + #2*#11)*3)
IC(#5,OVERWRITE) IC(#6,OVERWRITE) IC(#7,OVERWRITE)
Return

/////////////////////////////////////////////////////////////////////
//
//  Get color of a pixel. #1 = x, #2 = y
//  Return: #5 = Red, #6 = Green, #7 = Blue
//
:GET_COLOR:
Goto_Pos((#1 + #2*#11)*3)
#5 = Cur_Char
#6 = Cur_Char(1)
#7 = Cur_Char(2)
Return

Visual Basic .NET

' The StructLayout attribute allows fields to overlap in memory.
<System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)> _
Public Structure Rgb

    <FieldOffset(0)> _
    Public Rgb As Integer

    <FieldOffset(0)> _
    Public B As Byte

    <FieldOffset(1)> _
    Public G As Byte

    <FieldOffset(2)> _
    Public R As Byte

    Public Sub New(ByVal r As Byte, ByVal g As Byte, ByVal b As Byte)
        Me.R = r
        Me.G = g
        Me.B = b
    End Sub

End Structure
Public Class RasterBitmap

    Private m_pixels() As Rgb

    Private m_width As Integer
    Public ReadOnly Property Width As Integer
        Get
            Return m_width
        End Get
    End Property

    Private m_height As Integer
    Public ReadOnly Property Height As Integer
        Get
            Return m_height
        End Get
    End Property

    Public Sub New(ByVal width As Integer, ByVal height As Integer)
        m_pixels = New Rgb(width * height - 1) {}
        m_width = width
        m_height = height
    End Sub

    Public Sub Clear(ByVal color As Rgb)
        For i As Integer = 0 To m_pixels.Length - 1
            m_pixels(i) = color
        Next
    End Sub

    Public Sub SetPixel(ByVal x As Integer, ByVal y As Integer, ByVal color As Rgb)
        m_pixels((y * m_width) + x) = color
    End Sub

    Public Function GetPixel(ByVal x As Integer, ByVal y As Integer) As Rgb
        Return m_pixels((y * m_width) + x)
    End Function

End Class

Wren

Library: DOME

The above library's ImageData class fits the bill here (version 1.3.0 or later).

import "graphics" for Canvas, ImageData, Color
import "dome" for Window

class Game {
    static bmpCreate(name, w, h) { ImageData.create(name, w, h) }

    static bmpFill(name, col) {
        var image = ImageData[name]
        for (x in 0...image.width) {
            for (y in 0...image.height) image.pset(x, y, col)
        }
    }

    static bmpPset(name, x, y, col) { ImageData[name].pset(x, y, col) }

    static bmpPget(name, x, y) { ImageData[name].pget(x, y) }

    static init() {
        Window.title = "Bitmap"
        var size = 600
        Window.resize(size, size)
        Canvas.resize(size, size)
        var bmp = bmpCreate("rcbmp", size/2, size/2)
        bmpFill("rcbmp", Color.yellow)
        bmpPset("rcbmp", size/4, size/4, Color.blue) // 'blue' is #29ADFF on the default palette
        var col = bmpPget("rcbmp", size/4, size/4)
        System.print(col.toString) // check it's blue - alpha component (FF) will also be shown
        bmp.draw(150, 150) 
    }

    static update() {}

    static draw(alpha) {}
}
Output:
Color (#29ADFFFF)

Xojo

Function CreatePicture(width As Integer, height As Integer) As Picture
  Return New Picture(width, height)
End Function

Sub FillPicture(ByRef p As Picture, FillColor As Color)
  p.Graphics.ForeColor = FillColor
  p.Graphics.FillRect(0, 0, p.Width, p.Height)
End Sub

Function GetPixelColor(p As Picture, x As Integer, y As Integer) As Color
  Return p.RGBSurface.Pixel(x, y)
End Function

Sub SetPixelColor(p As Picture, x As Integer, y As Integer, pColor As Color)
  p.RGBSurface.Pixel(x, y) = pColor
End Sub

XPL0

include c:\cxpl\codes;  \include 'code' declarations
def Width=180, Height=135, Color=$123456;
int X, Y;
[SetVid($112);  \set display for 640x480 graphics in 24-bit RGB color
for Y:= 0 to Height-1 do    \fill area with Color one pixel at a time
    for X:= 0 to Width-1 do \(this takes 4.12 ms on a Duron 850)
        Point(X, Y, Color);
Move(60, 60); HexOut(6, ReadPix(0,0));  \show color of pixel at 0,0
X:= ChIn(1);            \wait for keystroke
SetVid(3);              \restore display to normal text mode
]

Yabasic

// Rosetta Code problem: http://rosettacode.org/wiki/Bitmap
// by Galileo, 07/2022

open window 200, 200
backcolor 255, 0, 0 // red

clear window

color 0, 255, 0	// green
dot 100, 100

c$ = getbit$(100, 100, 100, 100)	// get color area 1x1 pixel
print c$
Output:
rgb 1,1:00ff00
---Program done, press RETURN---

zkl

This solution creates a PPM image. No error checking or clipping.

class PPM{	// (0,0) is logically bottom left
   fcn init(width,height){
      sz:=width*height*3;
      var [const] 
         data=sz.pump(Data(sz),0),  // initialize to Black (RGB=000)
	 w=width, h=height;
   }
   fcn fill(rgb){
      sz:=data.len()/3;
      data.clear(); sz.pump(data,T(Void,rgb.toBigEndian(3)));
   }
   fcn __sGet(x,y)    { data.toBigEndian(3*y*w + 3*x,3);        } //ppm[x,y]
   fcn __sSet(rbg,x,y){	data[3*y*w + 3*x,3]=rbg.toBigEndian(3); } //ppm[x,y]=rgb
   fcn write(out){   // write bottom to top to move (0,0) from bottom left to bottom left
      out.write("P6\n#rosettacode PPM\n%d %d\n255\n".fmt(w,h));
      [h-1..0, -1].pump(out,'wrap(h){ data.seek(3*h*w); data.read(3*w) });
      out.close();
   }
}
ppm:=PPM(256,256);
ppm.fill(0x00FF88);
foreach x in ([50..200]){ ppm[x,50]=0xff|00|00; } // horizontal red line

ppm.write(File("foo.ppm","wb"));
Output:
$ zkl hexDump foo.ppm | less
   0: 50 36 0a 23 72 6f 73 65 | 74 74 61 63 6f 64 65 20   P6.#rosettacode 
  16: 50 50 4d 0a 32 35 36 20 | 32 35 36 0a 32 35 35 0a   PPM.256 256.255.
  32: 00 ff 88 00 ff 88 00 ff | 88 00 ff 88 00 ff 88 00   ................
  48: ff 88 00 ff 88 00 ff 88 | 00 ff 88 00 ff 88 00 ff   ................
  64: 88 00 ff 88 00 ff 88 00 | ff 88 00 ff 88 00 ff 88   ................
  80: 00 ff 88 00 ff 88 00 ff | 88 00 ff 88 00 ff 88 00   ................
...