Reputation: 43
I have to flip the image horizontally but when I put in my code it only flips half of so that it reflects halfway through the image. What am I doing wrong?
public static void flipVertical(Pixel[][] imageArr)
{
int height = imageArr.length;
int width = imageArr[0].length;
for(int row = 0; row < height; row++)
{
for(int col = 0; col < width; col++)
{
Pixel p = imageArr[row][col];
imageArr[height - row - 1][col] = p;
}
}
Upvotes: 3
Views: 9543
Reputation: 140319
Your code doesn't work currently because it is copying the flipped bottom half of the image into the top half without keeping the original data in the top half of the image. As such, when it processes the bottom half of the image, it is effectively copying the same data back to the bottom half again.
When you swap two values, a
and b
, you would need to use a temporary variable:
Pixel tmp = a;
a = b;
b = a;
If you do it like you have:
a = b; // After, a == b and b == b.
b = a;
then the second assignment is effectively a no-op, since a
's value is already b
.
As such, you need to update your inner loop to:
Pixel p = imageArr[row][col];
imageArr[row][col] = imageArr[height - row - 1][col];
imageArr[height - row - 1][col] = p;
Also, the outer for loop should be:
for(int row = 0; row < height/2; row++)
Otherwise you flip the image, and then flip it back again.
Upvotes: 2
Reputation: 36391
What do you mean by flipping the image horizontally? It seems taht you want to swap it vertically... Swapping horizontally (resp. vertically) means mirroring it through vertical (resp. horizontal) axe.
Anyway. Two things : swap pixels correctly and limit your loop to half the dimension (once you swap two pixels, you don't need to swap them again) :
public static void flipHorizontal(Pixel[][] imageArr)
{
int height = imageArr.length;
int width = imageArr[0].length;
for(int row = 0; row < height; row++)
{
for(int col = 0; col < width/2; col++)
{ // swap two symmetric pixels
Pixel tmp = imageArr[row][col];
imageArr[row][col] = imageArr[row][width-col-1];
imageArr[row][width-col-1] = tmp;
}
}
}
Upvotes: 0
Reputation: 31689
The problem is that you're changing pixels that you will still need later. When row
goes through the top half of the rows, you modify the pixels in the bottom half by copying them from the top half. When row
later goes through the bottom half of the rows, you try to modify the pixels in the top half by copying them from the bottom half--but the first half of the algorithm already changed the bottom half. So you're not copying the original pixels when you set the top half.
There are at least two ways to solve this:
(1) Don't use the same array. Create a new array to hold the result, and copy after you're done.
(2) Let row
go only up to half the height, and for each loop iteration, swap the pixels in imageArr[row][col]
and imageArr[height-row-1][col]
, something like:
Pixel p1 = imageArr[row][col];
Pixel p2 = imageArr[height-row-1][col];
imageArr[row][col] = p2;
imageArr[height-row-1][col] = p1;
(Specifically, you want to do this only as long as row < height-row-1
. When you reach a point where row >= height-row-1
, then you have to exit the loop. Otherwise you're going to start undoing the work you've already done.)
Upvotes: 1
Reputation: 172408
You can use the AffineTransform class and its method translate
to flip the image horizontally. See the code here:
// Flip the image horizontally
tx = AffineTransform.getScaleInstance(-1, 1);
tx.translate(-image.getWidth(null), 0);
op = new AffineTransformOp(tx, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
image = op.filter(image, null);
Upvotes: 1