IMAGE
IMAGE [#handle | fileName | http://path-to-file.png | image-var | array of pixmap data]
The IMAGE statement provides access to extended support for image manipulation. There are two supported image formats: PNG and XPM (see below).
Image access
Create via open file handle
Open "circle.png" For Output As #1
Image(#1) i =
Create via file name
Image("circle.png") i =
Create via URL (note only works with HTTP not HTTPS)
Image("http://pngimg.com/uploads/tesla_car/tesla_car_PNG26.png") i =
Create via screen scrape (x, y, width, height)
Image(10, 10, 100, 100) i =
Create via another image variable
Image(...)
k = Image(k) i =
Create via 2D array
'Create image array a1 without transparency
dim a1(100, 200)
For y = 0 To 99
For x = 0 To 199
5: g += 10: b += 15
r += rgb(r%255, g%255,b%255)
a1(y, x) = Next
Next
'Create image array a2 with transparency
'Transparency is a value between 0 and 255
'0 is fully transparent; 255 is solid
dim a2(100, 200)
255: g = 255: b = 255
r = For y = 0 To 99
5
alpha = For x = 0 To 199
0.1
alpha += round(alpha) * 10
transparency = lshift 24) - rgb(r,g,b)
a2(y, x) = (transparency Next
Next
'Create and display images
Image(a1)
i1 = Image(a2)
i2 =
20,20)
i1.show(0,0) i2.show(
Create via array of X_PixMap data
"16 18 4 1"
im << "@ c #547B43"
im << " c #ffffff"
im << "+ c none"
im << "x c #ff0000"
im << "@@@@@@@+++++++++"
im << "@ @++++++++++"
im << "@ @+++++++++++"
im << "@ @++@++++++++"
im << "@ @@+++++++++"
im << "@ @+++@+++++"
im << "@ @++@@++++@"
im << "@ xxx @@ @++@@"
im << "@ xxx xx@@ @"
im << "@ xxx xxx @"
im << "@ xxxxxx @"
im << "@ xxxx @"
im << "@ xxxxxx @"
im << "@ xxx xxx @"
im << "@ xxx xxx @"
im << "@ xxx xxx @"
im << "@ @"
im << "@@@@@@@@@@@@@@@@"
im << Image(im) i =
Show command
zIndex controls whether the image will be displayed over or under another image. Images with higher zIndex values are drawn over the top of images with lower zIndex values. Opacity controls whether to display the image as solid or semi-transparent. Opacity values range from 1-100, with higher opacity values making the image less transparent. The default is 100 resulting in a solid image. When calling the show command a second time with new coordinates, the image will move to the new position.
i.show([x,y [,zindex [,opacity]]])
Hide command
The hide command hides the image from display
i.hide()
Draw command
The draw command draws the image immediately to the screen. Calling the draw command a second time with new coordinates, will draw the same image a second time at the new position to the screen.
draw([x,y [,opacity]]) i.
Save command
The save command saves the image data into the given file handle, file name or array
dim png
i.save(png)
Clip command
Clips the image. Next draw or show command will display only this part of the image. On the same image a new clip can be set.
left, top, width, height) i.clip(
Filter command (console version only)
Calls the supplied callback function on each pixel
func colorToAlpha(x)
return x
end
use colorToAlpha(x)) png.filter(
Paste command (console version only)
Paste the given image into this image at the given x, y location
Image(w, h)
png2 = png2.paste(png1, x, y)
Example 1
Const CSI_EL = Chr(27) + "[K" ' EL - Erase in Line (clear to end of line).
Sub title(txt)
Locate 0, 0: Color 7, 0: ? CSI_EL; txt;
End Sub
' Draw a demo image with text on screen:
"Draw a demo image")
title(Pset 100, 100
Circle Step 0, 0, 50 Color 7 Filled
Circle Step 0, 0, 35 Color 1 Filled
"Hello"
text = At Point(0) - Txtw(text) \ 2, Point(1) - (Txth(".") \ 2)
Color 14, 1: Print text;
Pause
"Create image from screen")
title(Image(50, 50, 102, 102) ' Create image from screen (x, y, width, height)
i = 350, 50) ' Show the image at location (x, y)
i.Show(Pause
"Hide the image")
title(' Hide the image
i.Hide() Pause
"Save the image to 2-D array (y, x) of pixels")
title(' Save the image to 2-D array (y, x) of pixels
i.Save(a) Image(a) ' Create a new image from the 2-D array
i2 = 200, 90) ' Show the new image at location (x, y)
i2.Show(Pause
"Modify the colors of the 2-D array (y, x)")
title(For y = 0 To Ubound(a, 1) ' Modify the colors of the 2-D array (y, x)
For x = 0 To Ubound(a, 2)
100
a(y, x) += Next
Next
Image(a) ' Create a new image from the modified 2-D array
i2 = 350, 50) ' Show the new image at location (x, y)
i2.Show(Pause
"Copy the top-left of the 2-D array (y, x)")
title(Ubound(a, 1) / 2 ' Copy the top-left of the 2-D array (y, x)
half_y = Ubound(a, 2) / 2
half_x = Dim a2(half_y, half_x)
For y = 0 To half_y
For x = 0 To half_x
a2(y, x) = a(y, x)Next
Next
Image(a2) ' Create a new image from the top-left 2-D array
i2 = 200, 90) ' Show the new image at location (x, y)
i2.Show(Pause
' Note: 'zindex' is probably order of layers - above/under other image(s).
"Show original image using zindex & opacity")
title(400, 100, 1, 50) ' Show original image (x, y, zindex, opacity)
i.Show(Pause
Image(i) ' Create a new image from original image
i3 = 440, 130, 0) ' Show the new image (x, y, zindex)
i3.Show(Pause
' Note: file name is case sensitive on Linux.
"Save & Load original image as a PNG file")
title(Open "circle.png" For Output As #1
1) ' Save original image as a PNG file
i.Save(#Close #1
Open "circle.png" For Input As #1
Image(#1) ' Load image from a PNG file
i4 = Close #1
600, 20) ' Show loaded image (x, y)
i4.Show(Pause
Example 2
' Notes:
' 1. Using POINT and PSET is a much slower option then using:
' i = IMAGE(x, y, width, height) and i.Show(x, y) - (See Part-1).
'
' 2. The 2-D array that holds the image, a(y, x), must be equilateral, e.g.
' a(2 To 6, 1 To 5), etc; Using a(1 To 5, 1 To 6), for example, is wrong.
'
' 3. It's possible to use POINT or RGB commands (alpha is not supported
' in this case) to create the 2-D array that holds the image, a(y, x).
Const CSI_EL = Chr(27) + "[K" ' EL - Erase in Line (clear to end of line).
Sub title(txt)
Locate 0, 0: Color 7, 0: ? CSI_EL; txt;
End Sub
' Draw a demo image with text on screen:
"Draw a demo image")
title(Pset 100, 100
Circle Step 0, 0, 50 Color 7 Filled
Circle Step 0, 0, 35 Color 1 Filled
"Hello"
text = At Point(0) - Txtw(text) \ 2, Point(1) - (Txth(".") \ 2)
Color 14, 1: Print text;
Pause
"Create 2-D image array from screen using POINT")
title(Dim a(49 To 152, 48 To 151) ' Create 2-D image array from screen using POINT
For y = 49 To 152
For x = 48 To 151
Point(x, y)
a(y, x) = Next
Next
Pause
"Show the 2-D array (slow) using PSET")
title(For y = 49 To 152 ' Show the 2-D array (slow) using PSET
For x = 48 To 151
Pset x + 150, y + 85, a(y, x)
Next
Next
Pause
"Show the image (fast) using SHOW")
title(Image(a) ' Convert the 2-D array (y, x) of pixels to image
i = 350, 230) ' Show the image (fast) at location (x, y)
i.Show(Pause
Example 3
' Notes:
' 1. You may load an existing XPM image file, the same way you load PNG image
' file; Or you may store the XPM data within the source code (DATA keyword
' can help with this...).
'
' 2. XPM is a text image file, as opposed to PNG which is a binary image file.
' XPM supports high quality images, for more details and options see:
' https://en.wikipedia.org/wiki/X_PixMap
' In this example we use the simple and handy XPM2 format (as opposed to the
' latter and more standard C format, XPM3);
' Create the XPM image array:
' a << "! XPM2" ' (We Don't use this header line in SmallBASIC 0.12.6)
"110 200 3 1" ' Width=110, Height=200, Colors=3, Character-Per-Pixel=1
a << "a c #FF0000" ' Character "a" is RGB(0xFF, 0x00, 0x00) - RED
a << "b c NONE" ' Character "b" is transparency color (NONE)
a << "c c #0000FF" ' Character "c" is RGB(0x00, 0x00, 0xFF) - BLUE
a << For i = 1 To 200 ' Create an image of exactly 110x200 (x,y) pixels
String(30, "a") + String(50, "b") + String(30, "c")
a << Next i
Color 1, 7: Cls
Image(a) ' Convert the XPM array to image
i = 150, 50) ' Show the image at location (x, y)
i.Show(At 150 - 100, 50 - 30
Print "This is XPM image with transparency!"
Pause
' More about XPM2 - from https://en.wikipedia.org/wiki/X_PixMap:
' --------------------------------------------------------------
' XPM2 simplifies the format by removing all C codes. An example:
' ! XPM2
' 48 4 2 1
' a c #FFFFFF
' b c #000000
' abaabaababaaabaabababaabaabaababaabaaababaabaaab
' abaabaababaaabaabababaabaabaababaabaaababaabaaab
' abaabaababaaabaabababaabaabaababaabaaababaabaaab
' abaabaababaaabaabababaabaabaababaabaaababaabaaab
' This is an XPM2 file with width 48, height 4, 2 colors, and 1 character per
' pixel.
' One tool is known to use only a to p for 16 colors, switching to aa up to dp
' for 64 colors, but still reading single character encodings for 64 colors;
' compare Base64.
'
' With more colors the codes use more characters, e.g. aa up to pp for
' 16 x 16 = 256 colors. This is less useful for text editors, because a string
' ab could be actually the middle of two adjacent pixels dabc.
' Spaces are allowed as color code, but might be a bad idea depending on the
' used text editor.
' Without control codes, space, and quote (needed in XPM1 and XPM3)
' 128 - 33 - 2 = 93 ASCII characters are available for single character color
' codes.
'
' Simplified example: 90 US-ASCII characters could be arranged into nine
' non-overlapping sets of 10 characters. Thus unambiguous strings of nine
' characters could set the color of each pixel by its XPM palette index with
' up to 109 = 1000000000 colors (compare to GIF, which supports only 256).
' For XPM2 it is clear how many lines belong to the image - two header lines,
' the second header line announcing the number of color codes (2 lines in the
' example above) and rows (height 4 in the example above),
' e.g. 2 + 2 + 4 = 8 lines.
Example 4
Color 7, 1: Cls ' (for recognizing transparency color)
' --- [1]
Restore Demo_XPM_Image ' Create a demo XPM image array
For i = 1 To 12
Read s
a << sNext i
Image(a) ' Convert the XPM array to image
i = 10, 10) ' [1] Show the image at location (x, y)
i.Show(Open "SB.png" For Output As #1
1) ' Save XPM image as a PNG file
i.Save(#Close #1
' --- [2]
Image("SB.png") ' Load image from PNG file, using a "file name"
i = 30, 30) ' [2] Show loaded image (x, y)
i.Show(
' --- [3]
Open "SB.png" For Input As #1
Image(#1) ' Load image from PNG file, using a file number
i = Close #1
50, 50) ' [3] Show loaded image (x, y)
i.Show(
' --- [4]
Open "SB.png" For Input As #1 ' Load image from PNG file into 1-D array of
Lof(1) ' PNG byte data (integers)
l = Dim a(1 To l) ' (It's much faster to allocate space first)
For i = 1 To l Do a(i) = Bgetc(1)
Close #1
Image(a) ' Create an image from the 1-D array
i = 80, 80) ' [4] Show loaded image (x, y)
i.Show(
' --- [5]
Import Base64 ' (See Base64 Encoder/Decoder UNIT above, or
' in: Home -- Code library -- Units section)
Restore Base64_encoded_PNG ' Load image from Base64 encoded PNG data
"" ' into 1-D array of PNG byte data (integers)
s = For i = 1 To 3
Read d
s += dNext i
' Decode Base64 PNG string to 1-D array
a = base64.Decode_Base64(s) Image(a) ' Create an image from the 1-D array
i = 100, 100) ' [5] Show loaded image (x, y)
i.Show(
' --- [6]
Restore Demo_XPM_Image ' Save XPM image array as XPM file
Dim a(1 To 12)
For i = 1 To 12 Do Read a(i)
Tsave "SB.xpm", a
Tload "SB.xpm", a2 ' Load image from XPM file into array of strings
Image(a2) ' Convert the XPM array to image
i = 120, 120) ' [6] Show loaded image (x, y)
i.Show(
' --- [7]
Open "http://smallbasic.sourceforge.net/images/logo.png" For Input As #1
Image(#1) ' Load PNG image from web (you must be on-line)
i = Close #1
150, 150) ' [7] Show loaded image (x, y)
i.Show(
Pause
End
' Note: you may use the Base64 Encoder/Decoder UNIT above to convert PNG file
' into Base64 encoded string (large file takes time to convert!).
' It allows you to store the PNG file within the source code.
Label Base64_encoded_PNG ' (With transparency color)
Data "iVBORw0KGgoAAAANSUhEUgAAABUAAAAJAQAAAAD1eFrbAAAAAnRSTlMAAHaTzTgAAAA"
Data "oSURBVHgBHcdBAQAwDMJA6qI/LLSOkDU5kzZYXhck8mKPMK3vsvOxe3i6Bu6pAW2gAA"
Data "AAAElFTkSuQmCC"
Label Demo_XPM_Image
Data "21 9 2 1" ' Width=21, Height=9, Colors=2, Character-Per-Pixel=1
Data ". c NONE" ' Character "." is transparency color (known as "NONE")
Data "o c #FFFFFF" ' Character "o" is RGB(0xFF, 0xFF, 0xFF) - WHITE
Data "....................."
Data "...ooooo...ooooooo..."
Data "..oo...oo..oo....oo.."
Data "..oo.......oo....oo.."
Data "...ooooo...ooooooo..."
Data ".......oo..oo....oo.."
Data "..oo...oo..oo....oo.."
Data "...ooooo...ooooooo..."
Data "....................."
Example 5
' Dedicated to johnno56
Const CSI_EL = Chr(27) + "[K" ' EL - Erase in Line (clear to end of line).
Sub title(txt)
Locate 0, 0: Color 7, 0: ? CSI_EL; txt;
End Sub
' Draw a demo image with text on screen:
"Draw a demo image")
title(Pset 100, 100
Circle Step 0, 0, 50 Color 7 Filled
Circle Step 0, 0, 35 Color 1 Filled
"Hello"
text = At Point(0) - Txtw(text) \ 2, Point(1) - (Txth(".") \ 2)
Color 14, 1: Print text;
Pause
Image(50, 50, 102, 102) ' Create image from screen (x, y, width, height)
i = Color 7, 0: Cls ' Erase the demo image.
' Note:
' 1. zIndex parameter is used for the IMAGE sub-command SHOW, its syntax is:
' SHOW([x,y [,zindex [,opacity]]])
'
' 2. 'zindex' is the order of layers, i.e. under or above other image layers.
' I'm not aware of any limits for how many image layers can be used.
'
' 3. Using 'zindex' is simple, for example: layer 0 is above layer -1;
' layer -8 is below layer -7; layer 11 is above layer 10; etc.
' In this example we show 9 images on different layers:
Dim i2(1 To 9)
For layer = 1 To 9
Image(i) ' Copy the demo image to new image
i2(layer) = ' Use temporay variable to hold image (for Show)
t = i2(layer) ' Change the 'x' and 'y' properties of t image:
50 + layer * 35
t.x = 50 + layer * 25
t.y = At t.x + 100, t.y: Color 7, 0 ' (for display text info)
' Change the 'zIndex' property of t image:
Select Case layer
Case 1: t.zIndex = 0 : ? " Using layer # 0"
Case 2: t.zIndex = -2 : ? " Using layer # -2 (below layer -1)";
Case 3: t.zIndex = -1 : ? " Using layer # -1 (below layer 0)";
Case 4: t.zIndex = 3 : ? " Using layer # 3 (above layer 2)";
Case 5: t.zIndex = 2 : ? " Using layer # 2 (above layer 1)";
Case 6: t.zIndex = -9 : ? " Using layer # -9 (below layer -8)";
Case 7: t.zIndex = -7 : ? " Using layer # -7 (below layer -6)";
Case 8: t.zIndex = -3 : ? " Using layer # -3 (below layer -2)";
Case 9: t.zIndex = 4 : ? " Using layer # 4 (above layer 3)";
End Select
"IMAGE # " + layer + ": " + Str(t)) ' Print image properties
title(' Show image (x, y, zindex)
t.Show() Pause
Next layer
Base64 decoder for example 4
REM Purpose: A Base64 Encoder/Decoder UNIT.
REM File name: base64.bas
REM Unit name: base64
REM Version: 1.0.1 21/05/2016
REM Author: Christian d'Heureuse; shian (See License below)
' Notes:
' 1. Translated from VBasic to SmallBASIC (shian).
'
' 2. Useful for IMAGE keyword, and for any binary-to-text encoding/decoding.
' Base64 is often used to embed binary data in source code.
'
' 3. Since this is a translated code, I did not add much comments about the
' encoding/decoding method... So for more details about it see:
' https://en.wikipedia.org/wiki/Base64
'
' 4. License:
' - A Base64 Encoder/Decoder. This module is used to encode and decode data
' in Base64 format as described in RFC 1521.
' - Home page: www.source-code.biz.
' - Code from: http://www.source-code.biz/snippets/vbasic/12.htm
' - License: GNU/LGPL (www.gnu.org/licenses/lgpl.html).
' - Copyright 2007: Christian d'Heureuse, Inventec Informatik AG, Switzerland.
' - This module is provided "as is" without warranty of any kind.
'
' -- Start Demo code --- --- --- --- --- --- --- --- --- --- ---
'
' Import base64 ' (Import from another .bas file)
'
' Const FILE = "SB.png" ' (Change it to any other file name)
'
' ' Example using a "file name":
' s = base64.Encode_Base64(FILE) ' Encode 1-D bytes-array to Base64-string
' a = base64.Decode_Base64(s) ' Decode Base64-string to 1-D bytes-array
'
' i = Image(a) ' Convert 1-D bytes-array to image
' i.Show(10, 10) ' Show image at location (x, y)
' Showpage
'
' ' Example using a file # (opened for input):
' Open FILE For Input As #1
' s = base64.Encode_Base64(1) ' Encode 1-D bytes-array to Base64-string
' Close #1
' a = base64.Decode_Base64(s) ' Decode Base64-string to 1-D bytes-array
'
' i = Image(a) ' Convert 1-D bytes-array to image
' i.Show(30, 30) ' Show image at location (x, y)
' Showpage
'
' ' Example using 1-D bytes-array (a):
' s = base64.Encode_Base64(a) ' Encode 1-D bytes-array to Base64-string
' a = base64.Decode_Base64(s) ' Decode Base64-string to 1-D bytes-array
'
' i = Image(a) ' Convert 1-D bytes-array to image
' i.Show(50, 50) ' Show image at location (x, y)
' Showpage
'
' Pause
'
' -- End Demo code --- --- --- --- --- --- --- --- --- --- --- ---
Unit base64
Export Encode_Base64, Decode_Base64
' Initialize the helper maps (this code executes only once at load time).
Dim Map1(0 To 63)
Dim Map2(0 To 127)
0
i = ' Set Map1
For c = 65 To 90: Map1(i) = c: i++: Next ' Asc("A") To Asc("Z")
For c = 97 To 122: Map1(i) = c: i++: Next ' Asc("a") To Asc("z")
For c = 48 To 57: Map1(i) = c: i++: Next ' Asc("0") To Asc("9")
43 : i++ ' Asc("+")
Map1(i) = 47 : i++ ' Asc("/")
Map1(i) = ' Set Map2
For i = 0 To 127 Do Map2(i) = 255
For i = 0 To 63 Do Map2(Map1(i)) = i
' Encodes a 1-D bytes array (integers) into Base64 format string.
' No blanks or line breaks are inserted.
' Parameters:
' InData 1-D bytes array containing the data bytes to be encoded;
' or, "File_Name" string to load into 1-D bytes array;
' or, File-Number (opened-for-input) to load into 1-D bytes array.
' Returns: a string with the Base64 encoded data (that you can embed in
' your source code).
Func Encode_Base64(InData)
Local Out ' (As Byte)
Local ODataLen, OLen, ILen ' (As Long)
Local ip0, ip, op ' (As Long)
Local i0, i1, i2 ' (As Byte)
Local o0, o1, o2, o3 ' (As Byte)
Local s, i, fn, f ' as SmallBASIC...
If Isarray(InData) Then ' 1-D bytes array (integers) supplied
Len(InData)
ILen = ' Make life easier by loading 1-D bytes array from file:
Else
Isnumber(InData) ' Set flag to close file
f = If f Then ' An opened file # (For Input) supplied
fn = InDataElse ' A "filename" supplied
Freefile
fn = Open InData For Input As #fn
Fi
Lof(fn)
ILen = Dim InData(1 To ILen) ' (It's much faster to allocate space first!)
For i = 1 To ILen Do InData(i) = Bgetc(fn)
If Not f Then Close #fn ' (Don't close file if File # supplied)
Fi
If ILen = 0 Then Encode_Base64 = "": Exit Func
4 + 2) \ 3 ' Output length without padding
ODataLen = (ILen * 2) \ 3) * 4 ' Output length including padding
OLen = ((ILen + Dim Out(0 To OLen - 1)
LBound(InData)
ip0 = ' Encode base64 bytes array (See Wikipedia for this...):
While ip < ILen
i0 = InData(ip0 + ip): ip++If ip < ILen Then i1 = InData(ip0 + ip): ip++ Else i1 = 0
If ip < ILen Then i2 = InData(ip0 + ip): ip++ Else i2 = 0
4
o0 = i0 \ Band 3) * 0x10) Bor (i1 \ 0x10)
o1 = ((i0 Band 0xF) * 4) Bor (i2 \ 0x40)
o2 = ((i1 Band 0x3F
o3 = i2
Out(op) = Map1(o0): op++
Out(op) = Map1(o1): op++Iff(op < ODataLen, Map1(o2), 61): op++ ' 61 is Asc("=")
Out(op) = Iff(op < ODataLen, Map1(o3), 61): op++ ' 61 is Asc("=")
Out(op) = Wend
"": For i In Out Do s += Chr(i) ' Bytes-to-String
s =
Encode_Base64 = sEnd Func
' Decodes a string from Base64 format.
' Parameters
' s a Base64 String to be decoded.
' Returns: a 1-D array containing the decoded data bytes (integers).
Func Decode_Base64(s)
Local IBuf, Out ' (As Byte array)
Local i0, i1, i2, i3 ' (As Byte)
Local b0, b1, b2, b3 ' (As Byte)
Local o0, o1, o2 ' (As Byte)
Local OLen, ip, op ' (As Long)
Local ILen = Len(s) ' (As Long)
Local i ' as SmallBASIC...
If (ILen Mod 4) Or (ILen = 0) Then ' Data error
Throw "Length of Base64 encoded input string is not a multiple of 4."
Fi
Dim IBuf(0 To ILen - 1)
For i = 1 To ILen Do IBuf(i - 1) = Asc(Mid(s, i, 1)) ' String-to-Bytes
While ILen > 0
If IBuf(ILen - 1) <> 61 Then Exit Loop ' 61 is Asc("=")
ILen--Wend
3) \ 4
OLen = (ILen * Dim Out(0 To OLen - 1) ' 1-D bytes array
' Decode base64 bytes array (See Wikipedia for this...):
While ip < ILen
i0 = IBuf(ip): ip++
i1 = IBuf(ip): ip++If ip < ILen Then i2 = IBuf(ip): ip++ Else i2 = 65 ' 65 is Asc("A")
If ip < ILen Then i3 = IBuf(ip): ip++ Else i3 = 65 ' 65 is Asc("A")
If i0 > 127 Or i1 > 127 Or i2 > 127 Or i3 > 127 Then
Throw "Illegal character in Base64 encoded data." ' Data error
Fi
b0 = Map2(i0)
b1 = Map2(i1)
b2 = Map2(i2)
b3 = Map2(i3)If b0 > 63 Or b1 > 63 Or b2 > 63 Or b3 > 63 Then
Throw "Illegal character in Base64 encoded data." ' Data error
Fi
4) Bor (b1 \ 0x10)
o0 = (b0 * Band 0xF) * 0x10) Bor (b2 \ 4)
o1 = ((b1 Band 3) * 0x40) Bor b3
o2 = ((b2
Out(op) = o0: op++If op < OLen Then Out(op) = o1: op++
If op < OLen Then Out(op) = o2: op++
Wend
Decode_Base64 = OutEnd Func
You may create a PNG image + transparency color with an external image editor, and then you may also decode it as a Base64 PNG string (to store it within the source code). Another useful option is to use XPM image format (See Part-3 above) with transparency color, instead of color number you just write NONE, like this:
"x c NONE" ' Character "x" is transparency color a <<
Console version example
The following creates a plist file and composite sprite sheet which can be used with cocos2d development
const backgnd = 0xFF5A5D39
const shadow = 0xFF080c08
const alpha = 0x5a5d39
const alphaShadow = 0x80080c08
dim tileset
"eating e0000.png", 13]
tileset << ["eating n0000.png", 13]
tileset << ["eating ne0000.png", 13]
tileset << ["eating nw0000.png", 13]
tileset << ["eating s0000.png", 13]
tileset << ["eating se0000.png", 13]
tileset << ["eating sw0000.png", 13]
tileset << ["eating w0000.png", 13]
tileset << ["headshaking e0000.png", 11]
tileset << ["headshaking n0000.png", 11]
tileset << ["headshaking ne0000.png", 11]
tileset << ["headshaking nw0000.png", 11]
tileset << ["headshaking s0000.png", 11]
tileset << ["headshaking se0000.png", 11]
tileset << ["headshaking sw0000.png", 11]
tileset << ["headshaking w0000.png", 11]
tileset << ["running e0000.png", 11]
tileset << ["running n0000.png", 11]
tileset << ["running ne0000.png", 11]
tileset << ["running nw0000.png", 11]
tileset << ["running s0000.png", 11]
tileset << ["running se0000.png", 11]
tileset << ["running sw0000.png", 11]
tileset << ["running w0000.png", 11]
tileset << ["stopped0000.png", 7]
tileset << ["walking e0000.png", 11]
tileset << ["walking n0000.png", 11]
tileset << ["walking ne0000.png", 11]
tileset << ["walking nw0000.png", 11]
tileset << ["walking s0000.png", 11]
tileset << ["walking se0000.png", 11]
tileset << ["walking sw0000.png", 11]
tileset << ["walking w0000.png", 11]
tileset << [
func colorToAlpha(x)
if (x == backgnd) then return alpha
if (x == shadow) then return alphaShadow
return x
end
sub print_include()
local j, pattern, count, out, varname
"#pragma once"
out << for j = 0 to len(tileset) - 1
0
x = 0
y =
[pattern, count] = tileset[j]translate(pattern, "0000.png", "")
varname = translate(varname, " ", "_")
varname = upper(varname)
varname = translate(pattern, "0000", "%04d")
pattern = "const char *" + varname + "_PNG = \"" + pattern + "\";"
out << "const int " + varname + "_PNG_SIZE = " + count + ";"
out << next j
tsave "Classes/horse.h", out
end
sub print_plist(byref images)
local plist, i
dim plist
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
plist << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
plist << "<plist version=\"1.0\">"
plist << "<dict>"
plist << " <key>texture</key>"
plist << " <dict>"
plist << " <key>width</key>"
plist << " <integer>" + w + "</integer>"
plist << " <key>height</key>"
plist << " <integer>" + h + "</integer>"
plist << " </dict>"
plist << " <key>frames</key>"
plist << " <dict>"
plist << for i = 0 to len(images) - 1
png = images[i]" <key>" + png.name + "</key>"
plist << " <dict>"
plist << " <key>x</key>"
plist << " <integer>" + png.x + "</integer>"
plist << " <key>y</key>"
plist << " <integer>" + png.y + "</integer>"
plist << " <key>width</key>"
plist << " <integer>" + png.width + "</integer>"
plist << " <key>height</key>"
plist << " <integer>" + png.height + "</integer>"
plist << " <key>offsetX</key>"
plist << " <real>0</real>"
plist << " <key>offsetY</key>"
plist << " <real>0</real>"
plist << " <key>originalWidth</key>"
plist << " <integer>" + png.width + "</integer>"
plist << " <key>originalHeight</key>"
plist << " <integer>" + png.height + "</integer>"
plist << " </dict>"
plist << next i
" </dict>"
plist << " </dict>
plist << "</plist>
plist << tsave "Resources/horse.plist", plist
tsave "linux-build/bin/Debug/MobileCup/Resources/horse.plist", plist
end
sub main(byref tileset)
local i, j, x, y, pattern, count, images, composite, width, height
dim images
0
width = 0
height =
for j = 0 to len(tileset) - 1
0
x = 0
y =
[pattern, count] = tileset[j]for i = 0 to count
image("images/horse/" + format(pattern, i))
png = 5, 5, 5, 5)
png.clip(use colorToAlpha(x))
png.filter(format(pattern, i)
png.name =
png.x = x
png.y = height1
x += png.width + iff(png.height > y, png.height, y)
y =
images << pngnext i
iff(x > width, x, width)
width =
height += ynext j
image(width, height)
composite = for i = 0 to len(images) - 1
png = images[i]
composite.paste(png, png.x, png.y)next i
"Resources/horse.png")
composite.save("linux-build/bin/Debug/MobileCup/Resources/horse.png")
composite.save(
print_plist(images)
print_include()end
main(tileset)