Closed choochootrain closed 5 years ago
I dun it!
I made the changes you suggested with a few small tweaks. The program now requires an image path when it initializes, turns the image into bits and makes those bits accessible publicly.
The encode function takes in a text message to encode, raises an error if the message is too long and asks the user to enter a shorter message or use a larger file. It also errors to the user is they enter nothing... I took your suggestion and packed the whole image with the message instead of trying to store the length of the bits to extract, much more elegant :). I wrap the message in a beginning and ending single quote (required during extraction...)
After encoding, the image turns back into a png and is saved to a new file
decode img takes in a path from which to decode an img from, doesn't require the text. The default path is the one encode saves to. It turns the image to binary, extracts all the least significant bits, returns the message.
Check it!
Still required:
Code still breaks if a users enters a double quote mark in the text input, working on it.....
I have to add a few more tests to makes sure the picture is a png image, img path isn't given etc....
But other than that, this look good?
looks good, add those tests!
also now you can start separating your test/library/tool code. your tests are already separate so thats good, but right now sample.rb
is both the library with all the steganography logic and also the script that you run to encode an image - i would separate out that part into something like the code above and remove all the hardcoded image paths and ImageManipulator.new
s from sample.rb
(also maybe rename it to image.rb
and delete the old file?)
moving forward you should keep those 3 types of code separate and you'll notice that it'll make things more convenient for you
Hmm I'm kinda confused what you mean by separating the script from the library code. The scripting was just to test the functionality of whether this works or not, if I was to take it out, whats the benefit of adding it to a new file if I'll be adding an interface a user can interact with? I'm not clear on what the objective is :p Are you saying I should bake it into a rails controller?
Also I think I've already removed all the hardcoded image path's (other than the script at the bottom I was using for testing) I've only hardcoded where to save the modified new img file, everything else is dynamic, right?
its all about abstraction - you wrote a functional routine for encoding and decoding messages in images. the next step is to turn it into a web app. when youre implementing the rails side of this, the details of how the encoding/decoding shouldn't matter at all because you've abstracted them away into an ImageManipulator
class with an encode
and decode
method that just do the right thing.
so the value is in treating this code as a black box as you move on to other parts of your project. but the only way the black box is useful is if it has the rightknobs/inputs/outputs on it. right now you can provide it an image, choose the text to encode, and also decode text. but as a user of the black box you don't have control over the fact that calling encode
will save the picture at ../encoded_pic.png
- so that harcoded file path should be an argument to the function.
Got it, makes sense. I've tweaked it so that the user can choose to specify which image path to save the encoded pic at and given it a default incase they don't care.
I've moved the encode, decode scripts for the sample test I was running to a separate folder tools. Let me know if this is not what you had in mind, tried looking up test/lib/tool structure, couldn't find much but I think this is what you were asking. Eventually I'm going under the assumption that I'll remove even this because the user will click buttons that have event listeners on the front end.
Still working on tests...
Strangest error just happened when I tried to run the script for initializing the pic, and then encoding it. Literally didn't change any code. This is probably really stupid but can't figure it out.
For some reason, when I run the script file (like I have been for the past month) I get an error saying the initialize function can't find the IronMonkey file, even though the path looks fine. So I tweaked it a bit and included the name of the dir (so instead of '../IronMonkey.png' if I do '../ChunkyPNG/IronMonkey.png' the initialize works. Super confused why this is happening now, was using the first path literally since writing the program.
Here is what the error looks like if I don't use the new path:
Kahaans-MacBook-Pro:ChunkyPNG kahaanpatel$ ruby tool/script.rb /Users/kahaanpatel/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/chunky_png-1.3.10/lib/chunky_png/datastream.rb:70:in
initialize': No such file or directory @ rb_sysopen - ../IronMonkey.png (Errno::ENOENT)
from /Users/kahaanpatel/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/chunky_png-1.3.10/lib/chunky_png/datastream.rb:70:in open' from /Users/kahaanpatel/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/chunky_png-1.3.10/lib/chunky_png/datastream.rb:70:in
from_file'
from /Users/kahaanpatel/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/chunky_png-1.3.10/lib/chunky_png/canvas/png_decoding.rb:45:in from_file' from /Users/kahaanpatel/Downloads/aa/ChunkyPNG/lib/image.rb:13:in
initialize'
from tool/script.rb:4:in new' from tool/script.rb:4:in
`
BUT even if I add the ChunkyPNG to the path, the encode script (which uses #binary_to_image) function won't work. I figured it was a path issue again so went tweaked the path and added the /ChunkyPNG bit again but this time expecting the function to encode the given image and create a new img file in my folder (like it has been) but no folder is created, and no error. WTF?! lol
I feel like this is something ridiculous obvious that I'm missing but not sure what lol...
I ran git diff to see what changed, here is the result:
`Kahaans-MacBook-Pro:ChunkyPNG kahaanpatel$ git diff diff --git a/encoded_pic.png b/encoded_pic.png deleted file mode 100644 index 756784e..0000000 Binary files a/encoded_pic.png and /dev/null differ diff --git a/tool/script.rb b/tool/script.rb index f7a7281..c2ddfbe 100644 --- a/tool/script.rb +++ b/tool/script.rb @@ -3,6 +3,6 @@ require_relative '../lib/image.rb'
img = ImageManipulator.new('../IronMonkey.png') # -img.encode('Career Karma ') +img.encode('Random message')
img.decode_message Kahaans-MacBook-Pro:ChunkyPNG kahaanpatel$ `
Any idea whats wrong?
Found my mistake, was very stupid....
whatever it was i guarantee you'll do something just as stupid or stupider the more time you spend coding :upside_down_face:
here's a really good example of that: https://github.com/MrMEEE/bumblebee-Old-and-abbandoned/commit/a047be85247755cdbe0acce6#diff-1
you have the core functionality down but now you have to think about how it will be used. it's useful to think about how you would use this code if someone else wrote it.
so here's a full encode and decode implementation using your library - by writing it out like this you should be able to spot exactly what you need to do to your code in order for this code to run:
Image
class toImageManipulator
or something more descriptive since it technically contains an image and modifies itdecode_message
shouldn't require the message to decode the message :upside_down_face: one easy way you can do this is by making sure the message fits exactly into the available space in the image. fix the bug above, and then for message that are shorter than the space available, add some whitespace (' '
) to the message until it is exactly the right length. now your decode function doesn't need the message or the message length to extract the message