Reflecting an image - java

This is part of a project for my computer science class. One of the tasks is to take an image and reflect it. I've already initialized a picture called image. When I run this method, instead of reflecting the picture it mirrors it.
public void reflect()
{
//Creating a for loop to get all of the x values for the image object
for(int x = 0; x < image.getWidth(); x++)
{
//Creating a nested for loop to get all of the y values for each x value
for(int y = 0; y < image.getHeight(); y++)
{
//Getting a pixel object for the given x and y value
Pixel pixelObj = image.getPixel(x, y);
//I'm pretty sure this next line is where I'm screwing up.
//It's probably really simple, but I can't figure it out.
Pixel newPixel = image.getPixel(image.getWidth()-x-1, y);
//This sets the color values of the new pixel to the ones of the old pixel
newPixel.setRed(pixel0bj.getRed());
newPixel.setGreen(pixel0bj.getGreen());
newPixel.setBlue(pixel0bj.getBlue());
}
}
image.show();
}

You have to swap the corresponding pixel values. Currently, you are overwriting the right half of the image before saving their pixel values in a reference for putting them to the left half.
Below I've illustrated what I mean by "swapping" value instead of just assigning them uni-directionally:
//Getting a pixel object for the given x and y value
Pixel pixelObj = image.getPixel(x, y);
Pixel oppositePixel = image.getPixel(image.getWidth()-x-1, y);
//Store the RGB values of the opposite pixel temporarily
int redValue = oppositePixel.getRed();
int greenValue = oppositePixel.getGreen();
int blueValue = oppositePixel.getBlue();
//This swaps the color values of the new pixel to the ones of the old pixel
oppositePixel.setRed(pixel0bj.getRed());
oppositePixel.setGreen(pixel0bj.getGreen());
oppositePixel.setBlue(pixel0bj.getBlue());
pixelObj.setRed(redValue);
pixelObj.setGreen(greenValue);
pixelObj.setBlue(blueValue);
If you swap pixels both ways in each round, it's sufficient to loop from 0 to image.getWidth() / 2.
Have a look how it's done in ImageJ's ImageProcessor class as a reference.
Another solution is to use a matrix transformation and scale by -1 in the x direction. See the ImageJ scale op for a more elaborate example using the ImgLib2 library for image processing in Java.

Related

Slick2d locating an x and y through pixel colour

I am trying to make holdable items for my slick2d game, I figured a good way to do this would be to have a hand on the player, to do this i have 1 pixel a unique colour, allowing me to locate that colour, and the x +y.
It worked perfectly until i tried to scale up the image and i get this crazy out of bounds exeception.
this is my code to find the x and y:
public int[] getLocation(Image i, Color c){
Image scaled = i.getScaledCopy(getWidth(), getHeight());
for(int x = 0; x < scaled.getWidth(); x++){
for(int y = 0; y < scaled.getHeight(); y++){
if(scaled.getColor(x, y).r == c.r && scaled.getColor(x, y).g == c.g && scaled.getColor(x, y).b == c.b){
int[] xy = {x,y};
return xy;
}
}
}
return null;
}
and this is how i use it
float x = (float) (getLocation(walkLeft.getCurrentFrame(), new Color(1, 1, 1))[0] + getX());
float y = (float) (getLocation(walkLeft.getCurrentFrame(), new Color(1, 1, 1))[1] + getY());
g.fillRect(x, y, 2, 2);
the exception is:
java.lang.ArrayIndexOutOfBoundsException: 16384
and it leads me back to this line:
if(i.getColor(x, y).r == c.r && i.getColor(x, y).g == c.g && i.getColor(x, y).b == c.b){
in the getLocation method..
I have a feeling its dead easy, yet its stumped me. Thanks to anyone to responds.
The loop(s) in getLocation loop over the dimensions of a 2x scaled copy of the Image, but then attempt to access the pixels of the original. Given the original is half the size, when you are half-way through the loop you will be out of bounds of the image dimensions. Either:
Don't scale the Image
If you must scale the Image, check the pixel value of the scaled image rather than the original.
As an aside, the code posted contains redundant calls...a) in getLocation if you are going to scale, consider scaling the image once rather than placing that code within the loop itself b) no need to call getLocation twice with the same parameters. Call it once and just use the returned array

Doesn't += return the newly assigned value?

I'm looping over image and summing the values of all pixels. I do this to create an integral image. To keep the last value easily available, I created the_sum variable to which I add values for each pixel.
If you know how integral image works, you know that every pixel in such image contains sum of all pixels before plus it's own value.
Hence:
integral_image[x][y][0] = (the_sum[0]+= (pixel & 0x00FF0000)>>16);
I increase the sum and assign it to current pixel. Netbeans IDE, however, warns me that I'm not reading from the_sum.
Something in the algorithm is broken and I'm not sure what is it. Is my approach wrong or is this a false positive report by NetBeans?
To avoid misunderstanding, this is the whole method:
/* Generate an integral image. Every pixel on such image contains sum of colors or all the
pixels before and itself.
*/
public static double[][][] integralImage(BufferedImage image) {
int w = image.getWidth();
int h = image.getHeight();
double integral_image[][][] = new double[w][h][3];
double the_sum[] = new double[3];
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
int pixel = image.getRGB(x, y);
integral_image[x][y][0] = (the_sum[0]+= (pixel & 0x00FF0000)>>16);
integral_image[x][y][1] = (the_sum[1]+= (pixel & 0x0000FF00)>>8);
integral_image[x][y][2] = (the_sum[2]+= pixel & 0x000000FF);
}
}
return integral_image;
}
Yes, += returns the newly assigned value. It is a false positive from netbeans.
At run time, the result of the assignment expression is the value of the variable after the assignment has occurred.
http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26

Weird rendering result when JFrame is set as not resizable, but not when it is resizable

I'm creating a game and I have a JFrame with a custom Canvas in it. The weird thing is that when I set the JFrame to BE RESIZABLE, the rendering result looks like this:
But when I set the JFrame to NOT BE RESIZABLE, the result looks like this:
The method which adds the texture's pixel array to the BufferedImage's pixel array looks like this:
// DRAW A TEXTURE ON THE CANVAS
public void drawTexture(Texture texture, Vector2i location) {
// Store the current texture coordinates
int tx = 0, ty = 0;
// Scroll through each pixel on the screen horizontally (begin at the X coordinate specified by the 'location')
for(int x = location.x; (x < getWidth() && x < location.x + texture.getWidth()); x++) {
// Scroll through each pixel on the screen vertically (begin at the Y coordinate specified by the 'location')
for(int y = location.y; (y < getHeight() && y < location.y + texture.getHeight()); y++) {
// Set each pixel to the color of the corresponding pixel on the Texture
pixels[x + y * getWidth()] = texture.getPixels()[tx + ty * texture.getWidth()];
// Add one to the texture Y coordinate
ty++;
}
// Reset the ty variable
ty = 0;
// Add one to the texture X coordinate
tx++;
}
}
And the BufferedImage is drawn inside of a loop in the run method of my custom canvas.
The custom canvas class (extends Canvas offcourse) implements Runnable, and it also contains an own Thread for rendering.
I wonder if anyone know why this happens, and maybe how to fix it, because I can't figure it out...
Well, I found the working answer here, because I found out that the Canvas was bigger than what I had set it to, so I googled for that, and that answer fixed both problems.
Quote from the answer to the other question:
Swap the pack and setResizable calls, so that pack is the second call.
and
This is a known "issue"
Question here.

Is there a way to find the size of a visible part of an image within an ImageView?

I'm looking for a way to find the dimensions of the visible part of an image is. The image I'm displaying in my ImageView is .png format, it has a portion that is "visible" and the rest is an invisible background.
Example Image:
←that box isn't visible on the real image, it's just to illustrate my point
So in this image there is only a small red wedge shape which is visible, but the full .png is really a rectangle of larger dimensions, thus I can't use something like bitmap.getWidth();
So:
How can I find out if a particular pixel in an image is "invisible" or not? Note: I know I can use bitmap.getPixel(x, y); to get a pixel, but I don't know what to do with it once I have it; is a test for 0 sufficient?
Is there a better way of finding the max width/height of the "visible" portion other than iterating through every pixel looking for the visible "end points"?
How can I find out if a particular pixel in an image is "invisible" or not? Note: I know I can use bitmap.getPixel(x, y); to get a pixel, but I don't know what to do with it once I have it; is a test for 0 sufficient?
Use image.getPixel(x, y) != Color.TRANSPARENT to check whether the pixel is visible or not.
Is there a better way of finding the max width/height of the "visible" portion other than iterating through every pixel looking for the visible "end points"?
There is no built in functions. You can use the below function to get the image in square shape leaving the transparent pixels out.
public static Bitmap removeTransparentPixels(Bitmap image) {
int x1 = image.getWidth();
int y1 = image.getHeight();
int width = 0, height = 0;
for (int x = 0; x < image.getWidth(); x++) {
for (int y = 0; y < image.getHeight(); y++) {
if (image.getPixel(x, y) != Color.TRANSPARENT) {
if (x < x1) {
x1 = x;
} else if (x > width) {
width = x;
}
if (y < y1) {
y1 = y;
} else if (y > height) {
height = y;
}
}
}
}
width = width - x1;
height = height - y1;
return Bitmap.createBitmap(image, x1, y1, width, height);
}
Make sure that your image doesn't contain only the transparent pixels. If the image has only transparent pixels then the statement Bitmap.createBitmap(image, x1, y1, width, height); will through exception.
There are probably some form of image processing libraries that you would need to take advantage of in order to achieve what you are requesting in order to keep the processing down if that is a concern such as OpenCV or ImageMagick that would probably get that information back to you in a quick manner via specific function calls.
As far as I know, there wouldn't be a built in way to determine that through a standard call into the image libraries that exist within Android. You would probably need to do some sort of heuristic check for transparent pixels as you mentioned with your original thought.

Random outofboundsexception being thrown for no reason?

I'm using LWJGL and Slick2D for a game I'm making. I can't seem to get it to draw the way I want it to be draw so I came up with an idea just to make my own drawing method. Basically it takes a image, a x, and a y and it goes through each pixel in the image, gets the color, then draws the image with the parameter x plus the x pixel it's on to get the position that the pixel is suppost to be drawn on. Same idea with the y. Although if the alpha channel isn't 255 for the pixel it doesn't draw it, although I'll fix that later. The problem is that whenever I run my code I get "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2044". I'm really confused. I'm hoping someone can figure out why this is happening.
private void DrawImage(Image image, int xP, int yP)
{
//xP And yP Are The Position Parameters
//Begin Drawing Individual Pixels
glBegin(GL_POINTS);
//Going Across The X And The Y Coords Of The Image
for (int x = 1; x <= image.getWidth(); x++)
{
for (int y = 1; y <= image.getHeight(); y++)
{
//Define A Color Object
Color color = null;
//Set The Color Object And Check If The Color Is Completly Solid Before Rendering
if ((color = image.getColor(x, y)).a == 255)
{
//Bind The Color
color.bind();
//Draw The Color At The Coord Parameters And The X/Y Coord Of The Individual Pixel
glVertex2i(xP + x - 1, yP + y - 1);
}
}
}
glEnd();
}
My answer is assuming that the texture is an array of data.
I have a feeling it is the getColor() method. Your for loop runs through and will use the height and width values. An array usually starts off with 0 and width and height are just array counts typically. So I can see when you reach HEIGHT, that the texture array will throw an exception.
Try removing the <= part and replace it with <
EXAMPLE:
for (int x = 1; x < image.getWidth(); x++)
It may also help you to start off with zero so you can get the entire image.
EXAMPLE
for (int x = 0; x < image.getWidth(); x++)
Here is a link on arrays.
This way, when you ask for the color at whatever position, it will never ask for a color reaching beyond what is in the texture array. Hopefully I made sense.

Categories