Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -1,10 +1,15 @@
Show a basic storage type to handle a simple RGB raster graphics image, and some primitive associated functions.
{{omit from|PARI/GP}}
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:
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|raster graphics operations]], and a basic output function to check the results is available in the article [[write ppm file]].''
''These functions are used as a base for the articles in the category [[Raster_graphics_operations|raster graphics operations]],
and a basic output function to check the results
is available in the article [[write ppm file]].''

View file

@ -20,7 +20,7 @@ final class Image(T) {
}
void allocate(in int nxx=0, in int nyy=0, in bool inizialize=true)
pure nothrow in {
pure nothrow @safe in {
assert(nxx >= 0 && nyy >= 0);
} body {
this.nx_ = nxx;
@ -34,8 +34,16 @@ final class Image(T) {
}
}
@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 in {
pure nothrow @safe in {
assert(nxx >= 0 && nyy >= 0 && data.length == nxx * nyy);
} body {
auto result = new Image();
@ -45,10 +53,10 @@ final class Image(T) {
return result;
}
@property size_t nx() const pure nothrow { return nx_; }
@property size_t ny() const pure nothrow { return ny_; }
@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
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));
@ -57,7 +65,7 @@ final class Image(T) {
return image[x + y * nx_];
}
T opIndex(in size_t x, in size_t y) const pure nothrow
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));
@ -66,7 +74,8 @@ final class Image(T) {
return image[x + y * nx_];
}
T opIndexAssign(in T color, in size_t x, in size_t y) pure nothrow
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));
@ -75,14 +84,15 @@ final class Image(T) {
return image[x + y * nx_] = color;
}
void opIndexUnary(string op)(in size_t x, in size_t y) pure nothrow
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 {
void clear(in T color=this.black) pure nothrow @safe @nogc {
image[] = color;
}
@ -94,7 +104,7 @@ final class Image(T) {
.split
.map!(row => row
.filter!(c => c == one || c == zero)
.map!(c => cast(T)(c == one))
.map!(c => T(c == one))
.array)
.array;
assert(M.join.length > 0); // Not empty.
@ -104,7 +114,7 @@ final class Image(T) {
}
/// The axis origin is at the top left.
void textualShow(in char bl='#', in char wh='.') const {
void textualShow(in char bl='#', in char wh='.') const nothrow {
size_t i = 0;
foreach (immutable y; 0 .. ny_) {
foreach (immutable x; 0 .. nx_)
@ -122,7 +132,7 @@ struct RGB {
}
Image!RGB loadPPM6(Image!RGB img, in string fileName) {
Image!RGB loadPPM6(ref Image!RGB img, in string fileName) {
if (img is null)
img = new Image!RGB;
auto f = File(fileName, "rb");

View file

@ -0,0 +1,57 @@
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)
}

View file

@ -1,5 +1,6 @@
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

View file

@ -1,33 +1,27 @@
class Pixel {
has Int $.R;
has Int $.G;
has Int $.B;
}
class Pixel { has Int ($.R, $.G, $.B) }
class Bitmap {
has @.data;
has Int $.width;
has Int $.height;
has Int ($.width, $.height);
has Pixel @.data;
method fill(Pixel $p) {
for ^$.width X ^$.height -> $i, $j {
@.data[$i][$j] = $p.clone;
}
method fill(Pixel $p) {
for ^$!width X ^$!height -> $i, $j {
self.pixel($i, $j) = $p.clone;
}
}
method pixel(
$i where ^self.width,
$j where ^self.height
--> Pixel
) is rw { @!data[$i*$!height + $j] }
method set-pixel ( $i, $j, Pixel $value) {
fail unless 0 <= $i <= $.width && 0 <= $j <= $.height;
@.data[$i][$j] = $value;
}
method get-pixel ($i, $j) {
fail unless 0 <= $i <= $.width && 0 <= $j <= $.height;
@.data[$i][$j];
}
method set-pixel ($i, $j, Pixel $p) {
self.pixel($i, $j) = $p.clone;
}
method get-pixel ($i, $j) returns Pixel {
self.pixel($i, $j);
}
}
# Usage:
my Bitmap $b = Bitmap.new( width => 10, height => 10);
$b.fill( Pixel.new( R => 0, G => 0, B => 200) );

View file

@ -0,0 +1,37 @@
/*REXX pgm demonstrates how to handle a simple RGB raster graphics image*/
red = '00000000 00000000 11111111'b /*define a red value. */
blue = '11111111 00000000 00000000'b /*define a blue value. */
blue = 'ff 00 00'x /*another way to define blue. */
image.= /*"allocate" an "array" to nulls.*/
call RGBfill red /*set the entire image to red. */
call RGBset 10,40,blue /*set a pixel to blue. */
x=10; y=40; pix=RGBget(x,y) /*get the color of a pixel. */
hexv = c2x(pix) /*get hex value of pix's color*/
binv = x2b(hexv) /* " binary " " " " */
say 'pixel' x","y '=' binv /*show the binary value of 20,50 */
bin3v = left(binv,8) substr(binv,9,8) right(binv,8)
say 'pixel' x","y '=' bin3v /*show again, but with spaces. */
say /*show a blank between bin & hex.*/
say 'pixel' x","y '=' hexv /*show again, but in hexadecimal.*/
hex3v = left(hexv,2) substr(hexv,3,2) right(hexv,2)
say 'pixel' x","y '=' hex3v /*show again, but with spaces. */
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────RGBFILL subroutine──────────────────*/
RGBfill: procedure expose image.; image.=arg(1); return
/*──────────────────────────────────RGBGET subroutine───────────────────*/
RGBget: procedure expose image.; parse arg Xpixel,Ypixel
return image.Xpixel.Ypixel /*get & return the pixel's color.*/
/*──────────────────────────────────RGBRASTER subroutine────────────────*/
RGBraster: procedure expose image.; parse arg Xsize,Ysize,color; RGB=
do x=1 to Xsize; _= /*build raster 1 line at a time. */
do y=1 to Ysize /* " a line " pixel " " " */
_=_ || image.x.y /*append single pixel to the line*/
end /*y*/ /* [↑] all done building a line.*/
RGB=RGB || _ /*append a single line to raster.*/
end /*x*/ /* [↑] all done building raster.*/
return RGB /*return RGB raster to invoker. */
/*──────────────────────────────────RGBSET subroutine───────────────────*/
RGBset: procedure expose image.; parse arg Xpixel,Ypixel,color
image.Xpixel.Ypixel=color; return /*define pixel, return to invoker*/

View file

@ -0,0 +1,111 @@
/* 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))

View file

@ -1,35 +0,0 @@
/*REXX program shows how to handle a simple RGB raster graphics image. */
image.='00 00 00'x /*set entire array to hex zeroes.*/
red='00000000 00000000 11111111'b /*define a red value. */
image.=red /*set the entire array to red. */
blue='11111111 00000000 00000000'b /*define a blue value. */
blue='ff 00 00'x /*another way to define blue. */
image.10.40=blue /*set a particular pixel. */
x=20
y=50
aPIXcolor=image.x.y /*obtain the color of a pixel. */
hexv=c2x(aPixcolor) /*get the binary value of 20,50. */
binv=x2b(hexv) /*get the binary value of 20,50. */
say 'pixel' x","y '=' binv /*show the binary value of 20,50 */
bin3v=left(binv,8) substr(binv,9,8) right(binv,8)
say 'pixel' x","y '=' bin3v /*show again, but with spaces. */
say 'pixel' x","y '=' hexv /*show again, but in hexadecimal.*/
hex3v=left(hexv,2) substr(hexv,3,2) right(hexv,2)
say 'pixel' x","y '=' hex3v /*show again, but with spaces. */
RGB= /*start with a clean slate. */
xSize=500 /*size of the X axis. */
YSize=800 /* " " " Y " */
do x=1 to xSize
do y=1 to Ysize
RGB=RGM || image.x.y /*build RBG one pixel at a time.*/
end /*y*/
end /*x*/
return RGM /*return the RGB image to invoker*/

View file

@ -0,0 +1,74 @@
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