this is @ignatz version, modified so that the encoding is multiline.
This is more easy to copy, embed several icons in one tab, etc…
--# Main
--Project: img2str
--Version: Alpha 1.0
--Comments: main author: @Ignatz
-- Compress
function setup()
parameter.text("info","Change image defined in Main tab")
parameter.action("Then click to create icon",createIcon)
end
function createIcon()
img1 = readImage("Documents:icon_key")
local str=Coder:Encode(img1)
loadstring(str)()
end
function draw()
background(208, 208, 214, 255)
if img then
text("Image from Tab",300,250)
sprite(img,300,150)
end
end
--# Coder
Coder = class()
--This function encodes an image in two strings
--the first string makes a list of unique color settings (r,g,b,a), encoded as an 8 char hex string
--the second string runs through the image, through rows then columns, and every time the color changes,
--it records the color setting and number of cells that had that color
--NB it doesn't store the color setting as an 8 char hex string, imstead it stores the position of
--this color in the first string. This saves a lot of storage where colors are used over and over again
local
Codes="!#&~*+,)/0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ-_`abcdefghijklmnopqrstuvwxyz"
-- 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
-- 1 2 3 4 5 6 7 8
function Coder:Encode(img)
local rows=img.height
local cols=img.width
local colors={} --hash table of unique colors, gives us their sequence in the unique list
local strCol="" --unique list of color settings, each one is 8 chars hex, for r,g,b,a
local str="" -- each item consists of a color setting (or rather, the position in strCol), and the number of
--cells to be colored
--for example, if the image starts with 56 cells with r=1,g=2,b=5,a=6, we will add the hex value of this,
--which is 001002005006, to strCol, and set colors[001002005006]=1, (1 because this is the first color)
--to str, we add the hex values of the string position, ie 1, and the number of cells, ie 56, so we will
--add 001038 to str
local colorCount=0
local prevColor=-1 --to tell us when the color changes
local count=0 --number of cells with current color
local r,g,b,a,x
local tbl={}
local tblCol={}
--loop through image
for i=1,cols do
for j=1,rows do
r,g,b,a=img:get(i,j)
x=r..","..g..","..b..","..a
if x==prevColor then
count=count+1
else --color has changed, store details of last color
if count>0 then --this will only be zero for the very first cell
y=colors[prevColor] --this looks up the position of the color, in the color list
if y==nil then --add the color to the list if not there
colorCount = colorCount + 1
y=colorCount
colors[prevColor]=colorCount
--if colorCount>1 then
--table.insert(tblCol,","..prevColor)
--else
table.insert(tblCol,prevColor)
--end
end
table.insert(tbl,y..","..count)
end
prevColor=x
count=1
end
if errMessage~=nil then break end
end
if errMessage~=nil then break end
end
--we've finished, but we may have some left over chars that need to be stored
if count>0 then
y=colors[prevColor]
if y==nil then
colorCount = colorCount + 1
colors[prevColor]=colorCount
y=colorCount
end
table.insert(tblCol,y)
table.insert(tbl,count)
end
str=table.concat(tbl,",")
strCol=table.concat(tblCol,",")
--create code for user
if errMessage~=nil then
print(errMessage)
return errMessage,errMessage
else
str1=Coder:Compress(strCol)
str2=Coder:Compress(str)
local final = Coder:PrintCode(cols,rows,str1,str2)
return final
end
end
function Coder:Compress(d)
local a={}
local m=0
local y,z
local x=string.gsub(d,"8","82")
x=string.gsub(x,"7","81")
x=string.gsub(x,"9","83")
x=string.gsub(x,",","7")
for i=1,#x,2 do
y=string.sub(x,i,i)*9
if i<#x then y=y+string.sub(x,i+1,i+1) else y=y+7 end
y=y+1
z=string.sub(Codes,y,y)
table.insert(a,z)
end
--return table.concat(a)
return self:concatN(table.concat(a),70)
end
local function splitString(s,n)
local out = {}
out[1] = ""
if #s <= n
then out[1] = s
else
for k = 1,math.ceil( #s/n ) do
out[k] = string.sub(s,(k-1)*n+1,k*n)
end
end
return out
end
function Coder:concatN(a,n)
local t = splitString(a,n)
local s = table.concat(t,'\
')
return s
end
function Coder:PrintCode(c,r,s1,s2)
local str =
"--image code\
img=Decoder:Decode("..c..","..r
..',\
[[\
'..s1.. '\
]]\
,\
[[\
'..s2.. '\
]]\
)'
saveProjectTab("ImageCode",str)
return str
end
--# Decoder
Decoder=class()
local
Codes="!#&~*+,)/0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ-_`abcdefghijklmnopqrstuvwxyz"
-- 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
-- 1 2 3 4 5 6 7 8
function Decoder:Decode(cols,rows,cc,dd)
local img=image(cols,rows)
local n=0
local m=4
local arrCols={}
cc = string.gsub(cc,"\
","")
dd = string.gsub(dd,"\
","")
strCol=Decoder:Decompress(cc)
strDat=Decoder:Decompress(dd)
--unpack color descriptions
for q in string.gmatch(strCol,"[^,]+") do
m = m + 1
if m==5 then
m=1
n = n + 1
arrCols[n]={}
end
arrCols[n][m]=q
end
--if m~=4 then print("faulty column codes, m=",m) end
--unpack RLE content
local col=1
local row=0
local ind=1
n=0
for q in string.gmatch(strDat, "[^,]+") do
if ind==1 then
colIndex=tonumber(q)
else
colCount=tonumber(q)
n = n + 1
for u=1,colCount do
row = row + 1
if row>rows then col=col+1 row=1 end
img:set(col,row,
color(arrCols[colIndex][1],arrCols[colIndex][2],arrCols[colIndex][3],arrCols[colIndex][4]))
end
end
ind=3-ind
end
return img
end
function Decoder:Decompress(a)
local s={}
local d1,d2,y,x
for i=1,#a do
y=string.find(Codes,string.sub(a,i,i))-1
d2=y%9
d1=(y-d2)/9
d2=d2
table.insert(s,d1)
table.insert(s,d2)
end
if s[#s]==7 then table.remove(s,#s) end
str=table.concat(s)
x=string.gsub(str,"7",",")
x=string.gsub(x,"81","7")
x=string.gsub(x,"83","9")
x=string.gsub(x,"82","8")
return x
end
--# ImageCode
--image code
img=Decoder:Decode(32,32,
[[
))))XnRXjTq2q2q2k#q6q6q6k3q:q:q:kA@doRdjt)@@@gsIsIsI9Ru7u7u7>-eo-ejtIu
)u)u)>@Yn-YjWo)`o)6tlllqIao7ajs7=kR=og_I_I_I6-8I8I8IXnsnsnsj_Istq8@stk
8IDl@DqBmtmtmtjGnnnj-777IPm-Pj?ntntntjbj@2j@Ej71j7Blslslsj+n7Un74RQmgQ
jAIggg8@6jg6m-tuqAItukSIuqIukRtsqA7tskNq8Isuq8I;@t@t@t@<7Km)Kj1msmsmsj
Dl-Gl-uujR4jRJIElIEqEmumumujJ@;k@;oIHlgHj&o@bo@84n)Tn)47t)t)t);-8@8@8@
Ul)Bl)tRAIAIAIt7sq7sk7s7s7s78J@hIhIhI8Dn@Vn@4sksksksq5q4q4q4k/7RRR2m@M
m@1sq0q0q0ju-A@A@A@stj-5j-Ml7Cl7tsj
]]
,
[[
7h7@7I7R7-7g7sjjkgtjqIR0jq777>q@7unj)7sjjkR-7uoj)7sjjkI0jqI71jj@73jqII
0jq777;jR75jjg777877umj)7sjjkR8@7uoj)74jjkI8I7ujk)7:jj)7ulj)74jjk@4jk@
7<jjjq@7umj)74jjkI=jk-7uoj)74jjk@=jj)7ujkg7A77R7ulj)74jktjkujl)72jl77:
jl@775jR7:jjjlI7unnjqIgFjjujl-775jR7I7ujR-78@774jR70jqI5lg7EjjjR4jj)7u
j-J774jjjR4jltjqI5lujjjRA@7uolg7KjkujjsjqIgJ7774m77unlg7MjjlmI7uoksjjj
I2jqI-OjjnmjqI-PjjjI2jqI-QjjnmsjqI-LjjjIS@7unkg77RsjmujqI-TjjjIUjqIgVj
jkq77@7uonI773kI7FjqIgXjjI79jqIgYjjj-ZjqI5nsjjj-WjltjqI3ojjjsjtjlg7uj7
_@7_I778@EjlsjqIuojkI779jR7`jmujqIR1jo77bjjk-cjn77djjg7Djlu
]]
)