On-the-fly Spinneret Web Graphics
Phil Pilgrim (PhiPi)
Posts: 23,514
In my Spinneret webcam, I use Spin methods to generate the BMP outputs for both the camera image and and the little colored bar graphs that show the camera's exposure settings and pan position. The bar graphs are generated one horizontal line at a time, starting at the bottom, from a generalized rectangle-pair drawing method. The two rectangles are nested and can have different colors. Here's an example that shows the parameters used to define it:
To create such an image, you can go here:
Feel free to experiment by changing the parameters to get different sizes and colors. As simple as it is, two nested rectangles like this can be used to create color swatches, horizontal and vertical bar meters, a point locatable on a two-dimensional rectangular background (for position tracking, say), among other graphical devices.
Here's the code that generates the rectangles:
-Phil
To create such an image, you can go here:
Feel free to experiment by changing the parameters to get different sizes and colors. As simple as it is, two nested rectangles like this can be used to create color swatches, horizontal and vertical bar meters, a point locatable on a two-dimensional rectangular background (for position tracking, say), among other graphical devices.
Here's the code that generates the rectangles:
VAR long zero[16] PUB do_rects(rwidth, rheight, rx, ry, rdx, rdy, rbg, rfg) | row_size, row, char, i, j, pix rwidth := rwidth #> 0 <# 512 rheight := rheight #> 0 <# 512 rx := rx #> 0 <# rwidth - 1 ry := ry #> 0 <# rheight - 1 rdx := rdx #> 0 <# rwidth - rx rdy := rdy #> 0 <# rheight - ry row_size := bitmap_header(rwidth, rheight, 1, @rbg) repeat ry [b]server.array[/b](@zero, row_size) repeat rdy repeat i from 0 to row_size - 1 repeat j from 0 to 7 pix := i << 3 + j char := char << 1 - (pix => rx and pix < rx + rdx) byte[@buffer][i] := char [b]server.array[/b](@buffer, row_size) repeat (rheight - ry - rdy) [b]server.array[/b](@zero, row_size) [b]server.end_custom_content[/b] PUB bitmap_header(img_width, img_height, bits_per_pixel, color_array) | i, j, colors, row_size wrword_bytes(@bmp_width, img_width) wrword_bytes(@bmp_height, img_height) bmp_bitspp := bits_per_pixel row_size := (bits_per_pixel * img_width + 31) >> 5 << 2 colors := 1 << bits_per_pixel wrword_bytes(@bmp_data_addr, $1a + 3 * colors) wrlong_bytes(@bmp_file_size, $1a + 3 * colors + row_size * ||img_height) [b]server.custom_content[/b] [b]server.array[/b](@bmp_hdr, @bmp_hdr_end - @bmp_hdr) repeat i from 0 to colors - 1 repeat j from 0 to 2 [b]server.out[/b](byte[color_array][i << 2 + j]) return row_size PUB wrlong_bytes(addr, data) wrword_bytes(addr, data) wrword_bytes(addr + 2, data >> 16) PUB wrword_bytes(addr, data) byte[addr++] := data byte[addr] := data >> 8 DAT bmp_hdr byte "Content-type: image/bmp",EOL byte "Cache-control: no-store",EOL,EOL byte "BM" bmp_file_size byte $4a,$18,0,0 byte 0,0,0,0 bmp_data_addr byte $4a,0 byte 0,0,$0c,0,0,0 bmp_width byte $80,0 bmp_height byte $60,0 byte $01,0 bmp_bitspp byte $04,0 bmp_hdr_endThe highlighted methods in the server object are as follows:
- custom_content: Begin the HTTP header:HTTP/1.1 200 OK
Connection: close - array: Output a block of bytes, beginning at the specified address and with a specified length.
- out: Output a single byte.
- end_custom_content: Close the socket, thus ending the transmission.
-Phil
Comments
-Phil