This week I began to prepare for my presentation. It is so difficult to force myself to stop working on my program. There are a few little things I want to fix still but what keeps happening is that I'll spend 1-2 hours trying to fix a small bug and I'll find that I still can't get my method to work and that I had wasted several hours that could have been spent documenting.
I still can't get my recovery algorithm to work any faster. I REALLY want to get that squared away before I do anything else but I don't think that there is enough time for that before my presentation. Perhaps I can reach out to kids from class to help me make my program more efficient.
0 Comments
This week I have been working towards putting the finishing touches on my project. Since presentations are only a week away, I have decided to stop working on trying to get extra features up and running. However, I did manage to fix one of the extra features which I had been toying around with throughout the semester. In order to compensate for the inconvenience of the size limitation for how large your hidden image can be, I have worked out a cropping algorithm.
I ended up having to add a new form to my project which allows the user to crop the hidden image by clicking and dragging a selection box. Although my cropping algorithm does it's job, I would like to tweak it if I have some time after I finish documenting my program. Speaking of documentation, I have about 2 days worth of documentation to finish before the end of this week. I also have to finish creating this website and do the complete the huge list of documents that need to be included with my source code. I set up some time with kids from class to work together on completing this list so that I don't accidentally forget something. Sometime tomorrow I will complete my project abstraction which is due this Tuesday. Since I am a terrible public speaker, I plan on practicing my presentation in front of at least 3 different people this week. I hope to finish creating my power point for the presentations by this week Saturday. So this week and last week I have been working on recovering my hidden image. I finally figured out what was causing my hidden image to look distorted after I had recovered it. The problem wasn't actually my algorithm to recover the image but rather my hiding algorithm that was flawed. The funny thing is, is that I have no idea exactly what I had done to fix my hiding algorithm to make my recovery algorithm all of a sudden start to work. In all honesty, I don't think I did anything. I had simply copied and pasted my code to recovery the image into a working backup copy of my project and after I added a few extra variables, my program finally recovered the hidden image without any distortions in appearance.
While I am really excited that my program can successfully hide and recover an image, there is room to improve in terms of efficiency. My program hides an image almost instantly. Unfortunately, the user waits for almost two full minutes to recover the image. I absolutely cannot figure out why that is. A friend of mine suggested to look for repetitive structures in my code that are unnecessary. I think what I really should do is try to find better methods that are used for processing large amounts of data. Earlier on in my program's construction, I had implemented a for loop to convert the hidden image stored as a byte array into a binary string right after it was initially uploaded by the user. When I ran my program and tried to hide an image, it would take almost 5 minutes after clicking upload for the hidden image to show up inside the picture box. To try to understand why this was taking so long I began to debug my program and quickly realized that it was my method which converted the hidden image from a byte array to a binary string that was causing the huge delay. I checked online for a better solution to solve this problem and quickly found an answer with only 2 lines of code on stackoverflow which worked perfectly. I think that I might be able to find a similar solution to my issue with recovering an image which will significantly decrease the wait time. I have also been trying to come up with a way to use my algorithm to hide bits from the image to hide in more than one bit of each pixel from the base image. I am finally starting to see why DCP wanted me to bitwise operators to shift the bits rather than my method of using the remainder function to tell if the least significant bit is even or odd..... My program has come a long way since my last post. It wasn't until I began to debug my program that I found several massive logic errors in my recover hidden image algorithm. Apparently, I was either copying over the wrong bits into the designated section of my base image which stores the hidden image's length (stored as a string of 1's and 0's). Since I was sure that my program was calculating the correct size and converting the correct binary string because I printed these values to a text file, I knew that a few simple control statements would probably fix this. Unfortunately, this was no simple task, and I had to learn the hard way that you should always make copies of your code when you're planning to making huge changes. Simply relying on the undo button can lead to serious issues. Even just commenting out your changes isn't as easy to reverse as just making back ups.
I had begun working on fixing this error Tuesday around 5 and by 4:00 am Wednesday morning my program would either crash or copy over the length of the hidden image at all. I went in to see DCP this afternoon and with embarrassingly little help from me, he was finally able to understand how my algorithm works. Which reminds me, I should probably practice explaining my program in preparation for my presentation at the end of April. Anyway, I'm happy to say that after my meeting with DCP I was able to locate the logic error and have remedied the problem. I now find myself faced with the daunting task of hiding an image that wasn't drawn by me in paint. I had always anticipated that there would be a huge limitation for the maximum size of the hidden image, however I had never actually tried to upload any data heavy images. I need to seek out some wisdom from DCP in order to figure out how to deal with this limitation. One idea I have right off the bat is to allow the user to crop the hidden image however they choose until it is small enough to fit inside the base image. More to come soon! Over break I successfully implemented an algorithm that hides an image inside another image. I still haven't done anything to indicate that I'm done reading and writing the message in my algorithm but I think i might just place eight 0's once my message write counter equals the length of the data to hide (stored in binary).
I am currently working on an algorithm to recover the hidden image from the base image. I hope to get most of this finished by the end of tomorrow. This week I researched the different types of files used for saving images. Stenography works by hiding data in the unused bits that composes a pixel in an image. That being said, it is imperative that the images used are formatted in a file type that does not compress the data. JPG files are one of the more commonly used files for saving images. While this file type supports 24-bit color, a major downfall of JPG files are their "lossy" nature as a result of data image compression. JPG file data compression is similar to the algorithm used in ZIP files, and the data loss is permanent. GIF files on the other hand do not compress the image data in anyway, however they have the drawback of being limited to an 8-bit color scale. PNGs are like GIFs in that they are "non-lossy", but with the added bonus of supporting 24-bit color making PNGs the ideal file type for my program.
I also begun looking into built-in bitwise operators in c#. I will be using the LSB of the RGB values that make up each pixel to hide my message. Luckily, with a quick Google search I was able to find an operator to shift the bits by one. My plan is to go through every 10th row in my base image and clear out the LSB, and replace it with the bit currently being processed in the bits that make up the hidden message. I am choosing to use every 10th row of pixels to hide my image in order to be as inconspicuous as possible. One question I have right away is how I am going to know when to stop reading the LSB my base image for the message. An obvious solution would be to just record the length of the hidden message and use a counter in my recover message method that reads the LSB bits until the counter has reached the length of the message. I could store the hidden message binary value into an array of chars and use the length function to compare the counter to the length to see if I am done reading the message. Last week I have been working with manipulating the red pixels in an image. DCP asked me to increase the red pixel value by 50. After searching online for an example of how this would be done, I was able to find a convert function in c# that converted an integer into it's byte equivalent, which I then replaced the original red pixels with. However, this isn't the way I had planned to do this. After speaking with DCP, he showed me a much easier way to change the red pixel value. I now have a function that can change the value of any of the pixels.
My next step which I will be working on this week will be to take a second image and place it within the first image. I am still a little unsure about how to go about doing that, but I have a good start so I plan on completing this task this week. After working on my capstone for several hours tonight, I've reached a point where I need to see either DCP or Dr. McVey in order to proceed any further.
C# has a built in Bitmap class, which I was successfully able to take advantage of. I currently have my programming working to change the pixels in every 10th row to pink, while the rest of the pixels remain the same I used the built in function getpixel to copy the RGB values into a temporary Color object, which I send to the function setpixel in order to redraw the original image, except with every 10th row filled in pink. All of this is contained within two for loops: one for the X coordinate and one for the y coordinate, continuously processing each pixel in the image until all have been processed. I attempted to try to copy the RGB values from the temporary color object I created into a new instance of my pixel struct, and use that pixel as a parameter in setpixel, however I got the warning "cannot convert data type" error from the setpixel function. My next step is to learn more about conversions of data types. I didn't save my blog entry for last week so I'll just sum up what I've been working on for the past two weeks in this one post.
I've been messing around with writing simple c# programs that allows a user to browse and upload an image from their pc. At this point I'm not too preoccupied with mastering c#. What I'm really concerned with is finding an algorithm for dealing with the individual pixels of the images I will be hiding. My research tonight (2/19/17) began by checking out the "How To" section of a student from the previous year who created a mosaic app. I finally am starting to get an idea about what data structures to use to represent a pixel. I also am in the middle of researching a getpixel() and putpixel() built in function for c#. Both will be handy for my project. It is 10:00 pm on Sunday and I have just sat down at my computer to start working on my capstone. I plan on working on making a C# program that puts an image on the screen. Veisha's mosaic project from last year will help me do this. DCP suggested that I start with hiding text in a picture and work up to hiding a picture in a picture.
I also need to update my resume. More to come about my success or failure with this later tonight. |
|