Forums Register Login

Looping through pixels in an image

+Pie Number of slices to send: Send
Hi, I'm trying to complete a challenge on HackThisSite.  The challenge is - there is a hidden message in the pixels in an image.  I need to loop through the pixels to find this message.  I've only started the challenge and I've ran into a problem.  Here is my code so far:



The problem is this line It doesn't recognise prog2, which is the image.  Am i using this wrong?    thanks
+Pie Number of slices to send: Send
hi  Bod,

what about the scope of a variable?    
+Pie Number of slices to send: Send
aaahhhh so my for loop needs to be inside the try block  thank you!  Its giving me a new error now but I'll try figure this one out before asking.  
+Pie Number of slices to send: Send
Or maybe simpler: put your Image outside the try block.

If I may give an advice, out of my own experience :

if you have a pixel(x, y), then x is the horizontal distance, i.e. the column, and y is the vertical distance, or the row. So, if you start looping from 0 to image.height, you are talking about the rows. Therefore, it is wise to name the loop variable 'row', instead of y. That has saved me from many index out of bound errors, where I messed up the columns and the rows, and thus the width and the height!
+Pie Number of slices to send: Send
Between Bods opening post and his first reply there was a reply about the scope of the Image variable, declared within the try-block. That reply got somehow lost in the transfer of this topc to another forum.
+Pie Number of slices to send: Send
Looks like your reply has been returned.  Thanks for the advice as I was probably have confused them also!  

To loop through the imagine pixels, the only thing I could find was using Raster() and BufferedImage().  Would this be the right route to go down or does anyone know of a method which only reads pixels?  I can't seem to find anything else.  I continue to write my code using these methods as I'm sure it can work this way.  
+Pie Number of slices to send: Send
A BufferedIamge is easy to use. When you read your image with ImageIO.read, you automatically get a BufferedImage. It has the method 'getRGB' that you can loop through. The int that you get from this method is in the form ARGB, with the alpha component in the bits 24-31. You xcan use the 'setRGB' to write to the BI.
+Pie Number of slices to send: Send
I've been reading into BufferedImage and RBG and have a question which might seem stupid.  I see that we only use 3 colours - blue, green and red in an integer value.  If all 3 are 255, does that mean the pixel is white?  As I'm trying to find white pixels in a picture.  
+Pie Number of slices to send: Send
 

Bod MacNeil wrote:I've been reading into BufferedImage and RBG and have a question which might seem stupid.  I see that we only use 3 colours - blue, green and red in an integer value.  If all 3 are 255, does that mean the pixel is white?  As I'm trying to find white pixels in a picture.  

Yes. Black is 0x000000 and white is 0xFFFFFF and red is 0xFF0000 and green is 0x00FF00 and blue is 0x0000FF.
+Pie Number of slices to send: Send
Agree, but don't forget that getRGB returns a 32-bit integer, with the bits 24-31 containing the alpha component. If that alpha is 255, then the pixel is fully opaque, if alpha is 0, then the pixel is completely transparant. Does a white pixel count as white in that case?

A simple check would be to first have a look at your BufferedImage (either in Java, or in Paint or similar), to see if it is easy to detect the hidden message. Success!
+Pie Number of slices to send: Send
I wish it was that simple :P  The hidden message is the space between all the pixels in the white dots in the picture.  So I need to loop through the picture, once It finds a white dot it stores the dots pixel location and moves on to the next.  I just have no idea how to get the program to detect a certain colour!

+Pie Number of slices to send: Send

Remember what I said about not mixing the row and the column?  

Well, if you have obtaibed the colour, as you do above, then you could do:


et cetera, and then test for:



Or should you test for colour NOT being white?
+Pie Number of slices to send: Send
I actually had this bit of code before but deleted it as my program didn't work, so I figured that was the problem.  It was clearly something else in the code that was the problem.

I only need to check for white pixels.  This is the image here:


So once we locate the first white pixel at the top, I save the location to an int, and then carry on looping to the next white pixel.  I will have a mess around with what you've suggested.  Thanks
+Pie Number of slices to send: Send
I did a quick test.  My loops seem to be looping through every pixel as the number of pixels were right, but its not picking up any colours when I use this:



This return 000.  Which at first I thought was black?  But if its picking the black up then it must also be picking up the white, which it is not.  IS there something Im missing in this?  thanks
+Pie Number of slices to send: Send
I fixed the problem.  It was code I had written earlier and forgot to remove that was causing the problem!!
+Pie Number of slices to send: Send
 

Piet Souris wrote:Or maybe simpler: put your Image outside the try block.

If I may give an advice, out of my own experience :

if you have a pixel(x, y), then x is the horizontal distance, i.e. the column, and y is the vertical distance, or the row. So, if you start looping from 0 to image.height, you are talking about the rows. Therefore, it is wise to name the loop variable 'row', instead of y. That has saved me from many index out of bound errors, where I messed up the columns and the rows, and thus the width and the height!


Piet, I'll have to disagree with you on this. Having done quite a bit of graphics programming X and Y are used almost exclusively, and ROW and COLUMN are nowhere to be found. Event the getRGB() method takes X and Y. I don't quite understand why you were running into out-of-bounds issues when using X and Y.
+Pie Number of slices to send: Send
hi Carey,

that's okay. I made this remark based on my own experience, but of course someone elses experience may be completely different.

If you compare the getRGB(x, y) to, say, array[x][y], where array is a 2D array (yeah I know, array of arrays   ) then there is a difference.
In array[x][y] the x is the row, going 'from top to bottom', and y is the column, 'going from left to right'. When dealing with the 'gerRGB(x,y), the situation is exactly reversed. The x is going from left to right (i.e. it is the column, going from 0 ti the widrh - 1), and y is going from top to bottom, ie is about the height. going from 0 to height - 1.

On more than one occasion, dealing with non square images, I mixed up the x and y, letting the x go from top to bottom like in the array, and got my index out of bounds errors. Since then I use consistently the notation array[row][column] for 2d arrays, and getRGB(column, row) for images.

I can imagine people finding this very personal notation of mine confusing. But don't say I didn't warn!    
+Pie Number of slices to send: Send
I have managed to loop through the image and find the white pixels.  This is the method which works.  



Whats happening here is once its finds a white pixel it saves the number in an ArrayList called rbgColours.  

The next thing I nee to do is convert these numbers to characters by using the method below.  We do this by measuring the distance between pixels and subtracting the first pixel location with the seconds.  


Once I ran the program I discovered that the hidden message was in morse code.  So I made another method to convert the more code to characters.  This method is below and uses a HashMap.


The last method also works.  The problem I am having is with the middle method sortArray();  When I run the program I get Null before the morse code.  Any ideas why, or a way around this?  Thanks.
+Pie Number of slices to send: Send
I posted the swrong method last.  Here is the HashMap method used to convert the code to ASCII.

+Pie Number of slices to send: Send
Hi Bod,

I'm afraid you posted your last post in the wrong topic. But can you explain the meaning of the counter values of IIRC, 32, 45 and 46? Are these white pixels always situated at these distances, even when split over more rows? But we'll done, it looks fine. And in case the message is about the location of a treasure: just send me a pm!    
+Pie Number of slices to send: Send
Your calls to morse.put() should be put in a static initializer block. You don't want to be doing those puts over and over for each choice.
+Pie Number of slices to send: Send
 

Carey Brown wrote:Your calls to morse.put() should be put in a static initializer block. You don't want to be doing those puts over and over for each choice.



AH that makes sense! thanks


Piet Souris wrote:Hi Bod,

I'm afraid you posted your last post in the wrong topic. But can you explain the meaning of the counter values of IIRC, 32, 45 and 46? Are these white pixels always situated at these distances, even when split over more rows? But we'll done, it looks fine. And in case the message is about the location of a treasure: just send me a pm!    



haha no treasure unfortunately  Here is a screenshot of the challenge as I'm not very good at explaining it.  It makes sense of the shite dots and what I'm trying to do.  


I've completed it now and are now onto the next challenge.  So no doubt I'll be posting a lot about that one :P
It was the best of times. It was the worst of times. It was a tiny ad.
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com


reply
reply
This thread has been viewed 8088 times.
Similar Threads
java image processing
Double drawing pixels when manipulating DataBuffer of a BufferedImage
Inserting an Image in JTextField
How to display an image in a Frame object
Drawing
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 17:58:58.