views:

409

answers:

3

Ok so I'm supposed to resize an image given to me by half using arrays. I have no idea where to begin. I'm given a function

public static int[][] resizeImage(int[][] original, int newWd, int newHt) 

and I'm supposed to use 2d arrays to map pixels from original to new image. Not sure if Im giving enough info. I dont want the answer, just a hint or starting point, because I'm just not sure how to even start with this.

+12  A: 

Ok, assuming a 100x100 image, if you had a blue pixel at [0,0] and a red pixel at [99][99], after the resizing where would you expect these pixels to be?

Tony Ennis
Ok well the blue pixel would stay at zero right, cuz we would take half of zero? And the red pixel would be at 49,49?
fprime
That's a perfectly good answer. How did you get [49][49]? Now, say you also have a yellow pixel at [98,98]. Where does that end up?
Tony Ennis
+1 for showing the way without telling the answer.
Matt Ball
I got 49 by dividing 99 by 2, and since its an int, it just becomes 49. 98 becomes 49,49 as well. Hmm, interesting. Is this right?
fprime
You're correct. You're going to have to make a hard decision. So now, you know how large the final image is. And you know one way to remap the points to the new array. Post your code when you're done!
Tony Ennis
Ok see edit....
fprime
+1 For the socratic approach ;)
Juan Pablo Califano
Up above, you mentioned something about dividing by 2. Where is this in your code?
Tony Ennis
OK what about now?
fprime
Explain to me what the assignment statement in the middle of the loops is doing.
Tony Ennis
@fprime. A couple of hints, if I may. You are reading from the newImage and writting to the original. You want to do it the other way around. Also, note that you are always reading the same pixel over and over. `newWd/2` and `newHt/2` will always return the same values within your loop. You might want to add `i` and `j` to the mix.
Juan Pablo Califano
It's taking the pixels at [i][j] and assigning them to the newImage at [i...ok wait..hmm..well were not really supposed to create this function just for scaling it in half, but for scaling it to whatever dimensions are given to us using newWd and newHt. So do we first have to find the ratio between original and and new dimensions to know where to place the new pixels?
fprime
re: assignment. The value on the left of the = is the one being changed.re: 2 - That's good. We were going there but you were faster :-D Now, look hard at that assignment statement. Which image is going to be written to?
Tony Ennis
Ok fixed, theres a test case for this code where we double the image size, so thats what I set it up above for-to double. Probably not right though.
fprime
Ok, so let's work through the loop. Say our original image is 20x20. If you're doubling the size of the image (similar to what you have) and you have a pixel at [10,10], where would you expect that pixel to end up? Look at your loop and use 2 for the scale factor and 10 for i and j.
Tony Ennis
+1 joining the group of admirers of the response.
Hemal Pandya
So I should get rid of the newWd and newHt and just have [i*2][j*2]? If a pixel is at 10,10, doubled should be at 20,20, but that only relocates the pixel. How do we double it? Should it occupy 20,20 and 21,21? or 19,19 and 20,20?
fprime
How the pixel is expanded... the image is getting twice as wide... the pixels get twice as wide. I'd probably go from 10 -> 20,21. TO know which way is right, where would [0][0] go if you were doubling the image? Now would be a good time to pull that 2 out into a variable outside of the array.
Tony Ennis
_I'm supposed to resize an image given to me by half using arrays._ so we also have to scale the image larger too? This is a little different, as we're finding out.
Tony Ennis
See edits please..
fprime
ok good. How would you feel about the two assignment statements in the inner loop if the scaling factor was 3? 4? 5?
Tony Ennis
Ok the multiplication is wrong then, should we add i and j?
fprime
It isn't wrong as such. It is along the right path. So, when we scaled the image by 2, a 1x1 pixel became a 2x2 pixel. You have 2 assignment statements, so that looks correct. What I mean is, how will you handle a scaling factor of 3? 5? 100? Are you going to put 100 assignment statements in there?
Tony Ennis
so another for loop? Not sure about this one
fprime
You're spot on. For now, let's stick with integer scale factors. Plop in a loop that does this. For now, assume integer scale factors >= 1.
Tony Ennis
Hmm ok..my head is starting to hurt:( Can we go a little faster, i mean whats the ultimate thing im going for here? I tried drawing it out on paper but its just confusing me. How would I use this for loop?
fprime
I made another for loop for (int s=0;s<scale;s++), is that right so far? How would I implement this?
fprime
You did it right. Now, you should be getting the value in the original array and writing it to every cell in the new array as per the `s` variable. You want a line like `newImage[scale*i+1][scale*j+1]=original[i][j];` but with `s` instead of 1. See how that will work? You'll quickly run into another, um, opportunity to learn, however. You new loop will add `s` to the X and Y coordinates, giving us a diagonal line instead of a solid block. We're gonna need _another_ loop, one will be for X, the other for Y.
Tony Ennis
code posted above.
Tony Ennis
OK so in the code above, i have scale=(newWt+newHt)/(oldWidth+oldHeight); but I dont really have anything for oldWidth and oldHeight. How would I determine these values? Would I use original.length for the length of the original array?
fprime
You have to be told what the scaling factor is, one way or the other. You could be told your original array is 3x3, your final should be 6x6 (I am assuming both dimensions will be scaled the same.) From this you can calculate the scale. scale = new_x_width/old_x_width.
Tony Ennis
ok see edits..still not working out though
fprime
At this point, using what you have plus the snippet I posted above, you should be well on your way to being able to scale the array larger with an integer scale factor. I have to hit the rack in 25 minutes. Just sayin'
Tony Ennis
`source.length` makes me queezy. Are you sure that returns one of the array dimensions? Stick a println on that or step through using the debugger and check it out.
Tony Ennis
I plugged in a constant of 2 for scale just to see if it would work, but I got an arrayindexoutofbounds exception of 4..
fprime
What were newHeight and newWidth?
Tony Ennis
w=6 h=8 ........
fprime
Look at your two outer loops. Are your sure you should be looping over the destination array's indexes? Maybe the original array's indexes would be better?
Tony Ennis
Hmm then I would use source.length again, whats the alternative to that? Or how could I use source.length to find height and width individually?
fprime
Holy crap I plugged in 3 and 4 for the original heights, and the function passed the test! Sweeettt..thanks man! Now I just gotta figure out how to find the original array length..
fprime
Wait I figured it out, i<newWidth/scale...thanks a lot man you've been a great help! I really appreciate it!
fprime
I did not know this - `original.length` gives us one dimension of the array. I do not know which. `original[0].length` gives us the other. Pheewwww.
Tony Ennis
You're welcome. I enjoyed helping, I hope you learned a lot. I have to hit the rack. Big day at work tomorrow!
Tony Ennis
+3  A: 

Draw a 4x4 grid on a piece of paper, and color each the squares with, say, one of red, green, blue, and black. Now draw an 8x8 grid, and picture how you would copy that picture from the first grid to the second. Notice what square in the original copied to what square in the target, and try to generalize that to an algorithm.

Obviously, the first grid is the original array, and the second grid is your returned array.

Did your teacher tell you how the picture should be resized? If not, you may just want to "make the pixels bigger", so each square is just copied straight to a 2x2 grid (four squares). You can get really, really fancy with your resizing algorithm (antialiasing, for instance), but I'd start simple.

Michael Petrotta
Yes he said: Hints: Use two nested for loops between 0... newWidth-1 and 0.. newHeight-1 inclusive. // Hint: You can just use relative proportion to calculate the x (or y coordinate) in the original image. // For example if you're setting a pixel halfway across the new image, you should be reading half way across the original image too.
fprime
@fprime: It *sounds* like the second hint is what I'm describing ("make the pixels bigger"). It gets interesting if you allow non-integral resizing (changing a 10x10 image to 14x14, for instance).
Michael Petrotta
A: 

This may help:
Interpolation algorithms when downscaling

pinichi