Just thought I'd drop this in here for a bit of fun.
I found an article online about encoding images into the RGB channel of other images, and thought that might be a fun little Livecode project to test my skills on.
I couldn't attach the stack here because of size issues of attachments... sorry!
So, here's an image of the setup as well as all the code for the back end. (Now with changes as per advice...)
Stacks/ substacks: Buttons, Hide, Code
Hide Stack has an image called "image"
Code stack has an image called "image" and a field called "Code"
Buttons stack has the following buttons, and their code-
'Load Image' (will load an image that will be encoded INTO
Code: Select all
on mouseup
NewImage
end mouseup
Code: Select all
global pChan
on mouseup
Put "1" into pChan
codeImage
end mouseup
- put 2 for G channel, put 3 for B channel
These will be used as an offset to isolate each individual channel of the image.
'Decode in R Channel'
Code: Select all
Global pChan
on mouseup
put "1" into pChan
DecodeImage
end mouseup
- put 2 for G channel, put 3 for B channel
'Save Image'
Code: Select all
on mouseup
SaveImage
end mouseup
Code is annotated to show what it's doing.
Code: Select all
global pChan
on openstack
open stack "Code"
open Stack "Hide"
end openstack
on NewImage
--load image from harddrive--
answer files "Select the image you wish to load:" with type "JPEG Images|jpg|JPEG"
--change the referenced image to new image--
set the filename of image "Image" of stack "Hide" to it
--Allow the stacks to be resized by code only--
set the resizable of stack "Code" to true
set the resizable of stack "Hide" to true
--track the w and h of image for scaling--
put the width of image "image" of stack "hide" into tWidth
put the height of image "image" of stack "Hide" into tHeight
--check dimensions of image fit on screen, if not, resize in scaled manner--
if tWidth > item 3 of the screenrect then
set the width of image "image" of stack "Hide" to (item 3 of the screenrect - 100)
set the height of image "Image" of stack "Hide" to ((width of image "Image" of stack "Hide" / tWidth)*theight)
end if
if tHeight > item 4 of the screenrect then
set the height of image "image" of stack "Hide" to (item 4 of the screenrect - 50)
set the width of image "Image" of stack "Hide" to ((height of image "Image" of stack "Hide" / tHeight)*twidth)
end if
--adjust stack sizes to image size, make sure both stacks are the same size--
Set the height of stack "Hide" to the height of image "Image" of stack "Hide"
Set the width of stack "Hide" to the width of image "Image" of stack "Hide"
Set the height of stack "Code" to the height of image "Image" of stack "Hide"
Set the width of stack "Code" to the width of image "Image" of stack "Hide"
--make the text for coding field the same size as the stack---
Set the height of fld "Code" of stack "Code" to the height of image "Image" of stack "Hide"
Set the width of fld "Code" of stack "Code" to the width of image "Image" of stack "Hide"
--make the dummy image the same size as the stacks--
Set the height of img "Image" of stack "Code" to the height of image "Image" of stack "Hide"
Set the width of img "Image" of stack "Code" to the width of image "Image" of stack "Hide"
--locate resized elements--
set the topleft of image "Image" of stack "Hide" to 0,0
set the topleft of Field "Code" of stack "Code" to 0,0
set the topleft of image "Image" of stack "code" to 0,0
--lock the stack sizes so they stay the same--
set the resizable of stack "Hide" to false
set the resizable of stack "Code" to false
--open the code stack if it isn't already open--
open stack "Code"
end NewImage
on SaveImage
--get location on harddrive--
ask file "Save to?" with type "JPEG Images|jpg|jpeg"
put it into tFile
--save the referenced image--
put image "image" of stack "Hide" into url ("binfile:" & tFile)
end SaveImage
--Coding based on image channel data being odd or even numbered.
--If it's odd, it will be shown as white, if it's even, it will be shown as black--
--When encoding, white pixel data that are odd and even pixel data this even will be skipped--
on CodeImage
go to stack "code" of this stack
--create jpeg of text field
export snapshot from card "Code" of stack "Code" to tCodeFile AS JPEG
--change dummy image to snapshot
set the TEXT of image "Image" of stack "Code" to tCodeFile
--check images are the same size, if not, issues will occur so abort--
if the width of image "Image" of stack "code" = the width of img "Image" of stack "Hide" and the height of img "Image" of stack "code" = the height of image "Image" of stack "Hide" then
--get the ARGB channel data of both images and put in container--
put the imagedata of image "Image" of stack "Code" into tCodeFileData
put the imagedata of image "Image" of stack "Hide" into tHideFileData
--work out how long the data is so it can be cycled through--
put the length of tHideFileData into tLength
--go through each 4th item of the data (i.e. one channel)--
repeat with i = 1 to tLength step 4
--look at every 4th character of code + an offset based on which channel is being used. Check if it's black (under 220) or white (over 220)----
if bytetonum(char i + pChan of tCodeFileData) > 220 then
--If it's white, check if it's an even number in picture file--
if (bytetonum(char i + pChan of tHidefileData))/2 is an integer then
--make it an odd number--
put (bytetonum(char i + pChan of tHideFileData)) + 1 into tCodePixel
--change corresponding character in picture file
put numtobyte(tCodePixel) into byte i + pChan of tHideFileData
end if
--Or, if it's black and an odd number, change it to an even number--
else if bytetonum(char i + pChan of tCodeFileData) <= 220 then
if (bytetonum(char i + pChan of tHidefileData))/2 is not an integer then
put (bytetonum(char i + pChan of tHideFileData)) + 1 into tCodePixel
put numtobyte(tCodePixel) into byte i + pChan of tHideFileData
end if
end if
end repeat
else
--if images aren't correct size, inform user--
answer "Your Images are not the same size"
end if
--change the images to suit altered pixels--
set the imageData of image "Image" of stack "Hide" to tHideFileData
set the cHiddenImageData of image "Image" of stack "Hide" to tHideFileData
end CodeImage
on DecodeImage
--Get the channel data of image to be decoded--
put the imagedata of image "Image" of stack "Hide" into tDecodeFileData
--get length so they can be cycled through--
put the length of tDecodeFileData into tLength
--Go through each 4th pixel--
repeat with i = 1 to tLength step 4
--Go through channel by looking at every 4th character + offest for channel. Check if it's odd--
if bytetonum(char i + pChan of tDecodeFileData)/2 is not an integer then
--change each channel to be white--
put numtobyte(255) into byte i +1 of tDecodeFileData
put numtobyte(255) into byte i +2 of tDecodeFileData
put numtobyte(255) into byte i +3 of tDecodeFileData
--If it's even--
else
--set the channels to be black--
put numtobyte(0) into byte i +1 of tDecodeFileData
put numtobyte(0) into byte i +2 of tDecodeFileData
put numtobyte(0) into byte i +3 of tDecodeFileData
end if
end repeat
--change the image to show coded text file--
set the imageData of image "Image" of stack "Hide" to tDecodeFileData
set the cHiddenImageData of image "Image" of stack "Hide"to tDecodeFileData
end DecodeImage
Was fun to play with, and threw out a good little problem of how to work out if a number is odd or even. I went with asking if the number divided by 2 was an integer (whole number). Only even numbers do that!
I have coded an image resize function so large images won't go over the screen size, but the encoding process takes a fair amount of time, so I wouldn't code big images (I have been working on 500x500). If anyone has a way of speeding up the process, I would love to hear it.
Enjoy!
XdM