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.
Related
Hi everyone – i am trying to draw a radial gradient in the background of my sketch – and I am trying to achieve this by manipulating the pixels like in an example by daniel shiffman – so far so good – it works as it should! BUT – now I want the radial gradient to be red – and the outer parts of the sketch to be black… So just as in the code example below, but inverted!
I tried many things – experimented with the RGB values – inverted the values of the dist(); function – thought of map(); – tried to change the calculations for the pixels – nothing worked out – what am I missing or can somebody explain it to me? I know what the code does – but cant get it inverted… does someone have an idea and can it explain it to me? I am really stuck…
void setup() {
size(1080, 1080);
}
void draw() {
loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
float d = dist(width/2, height/2, x, y);
pixels[x+y*width] = color(255,d,255);
}
}
updatePixels();
}
Thank you for any kind of help!
Here you go:
void setup() {
size(1080, 1080);
}
void draw() {
loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
float d = dist(width/2, height/2, x, y);
pixels[x+y*width] = color(255-d, 0, 0);
}
}
updatePixels();
}
Here's the trick:
RGB means Red-Green-Blue. They are the three colors which, mixed together, will make up the other colors. The number is how light the color is, so [255, 0, 0] would be a bright red. 255 everywhere would be white, and 0 everywhere would be black.
Your were close by trying to invert the dist, but the easy answer here was to invert it at the color's level by letting it range from 255 instead of to 255. That's why I wrote it 255 - d. Then, the further from the center, the closer to zero.
Have fun!
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
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.
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.
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.