I have been wanting file IO for a few projects I have been dreaming up and I had an idea: encode the text into a image and save that. So I wrote some code that does just that perfectly, it encodes text (I have tested it with pretty long blocks of text) into images. The way it works is by using the string.byte and string.char functions to convert characters into their ASCII codes, a number between 1 and 255. I then can encode 4 characters into each pixel of an image by setting the RGBA to the ASCII values.
I had a feeling that there might be a problem when I wrote it out to PNG though, figuring that after encoding/compression/dithering whatever I wouldn’t get the exact same pixels back. The problem I didn’t foresee is that when I load the image on my iPad 3 retina, the image size is doubled, and scaling it down seems to cause corruption. Converting to PNG might be corrupting it anyway, not sure.
I am posting my encode/decode functions below in case someone is smart enough to figure out how to get it properly working. I had imagined having programs and text files all saved in my documents folder as garbled looking image files, and was pretty excited to have it. Any help appreciated.
function DecodeToString(img)
local r,g,b,a
local dstr = ""
for y=1, img.height do
for x=1,img.width do
r,g,b,a = img:get(x,y)
if r ~= 0 then dstr = dstr .. string.char(r) end
if g ~= 0 then dstr = dstr .. string.char(g) end
if b ~= 0 then dstr = dstr .. string.char(b) end
if a ~= 0 then dstr = dstr .. string.char(a)end
-- this is slow, I will speed this up later
end
end
return dstr
end
function EncodeToImage(str)
local rem = string.len(str)
local len = rem
local lines = 1
while rem > 2000 do
lines = lines + 1
rem = rem - 2000
end
local img = image(500,lines)
img.premultiplied = true
for x=1, img.width do
for y=1,img.height do
img:set(x,y,0,0,0,0)
end
end
local p1, p2, p3, p4
local col = 1
local row = 1
local i = 1
while i <= string.len(str) do
p1 = 0
p2 = 0
p3 = 0
p4 = 0
p1 = string.byte(str,i)
if len >= i + 1 then p2 = string.byte(str,i+1) end
if len >= i + 2 then p3 = string.byte(str,i+2) end
if len >= i + 3 then p4 = string.byte(str,i+3) end
img:set(row,col,p1,p2,p3,p4)
row = row + 1
if row > 500 then
row = 1
col = col + 1
end
i = i + 4
end
return img
end
BTW I know it needs to be optimized, I will work on that if we can get the proof of concept working. Thanks.