LibGDX - get currently rendered screen as a matrix of RGB values - java

In the middle of a game, I'd like to have access to the pixels being currently displayed on the screen as a matrix (or really several matrices) of RGB values. Is there an easy command to access this?

You can use the code from [official LibGDX wiki[(https://github.com/libgdx/libgdx/wiki/Taking-a-Screenshot)
byte[] pixels = ScreenUtils.getFrameBufferPixels(0, 0, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), true);
Pixmap pixmap = new Pixmap(Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), Pixmap.Format.RGBA8888);
BufferUtils.copy(pixels, 0, pixmap.getPixels(), pixels.length);
//Your logic here
pixmap.dispose();
Then you can get desired pixel by using Pixmap method:
getPixel(int x, int y)
or just iterate over all pixels by using loop as following
for(int w = 0; w < pixmap.getWidth(); w++)
for(int h = 0; h < pixmap.getHeight(); h++)
getPixel(w, h);
Remember that pixmap needs to be disposed. List of objects that need to be dispose you will find here

Related

javafx update pixels every frame

For a project I'm working on, I need to animate an ocean through salinity colormaps. Essentially, I have salinity data for n timesteps and I need to update the pixel colors to match the current salinity values.
Right now I'm going through every pixel on a canvas in a nested for-loop and, for each pixel, computing the current salinity value at that pixel and updating the pixel's color to match the salinity value.
I keep track of the frames with a AnimationTimer object. The problem is that I'm getting around 20 fps and the application is lagging on events like resizing the window.
private void drawHeatMap(int depth, float t) {
float meanSalt = model.getMeanSalinity(depth);
float stdSalt = model.getSalinityStdDev(depth);
Colorbar colorbar = new Colorbar(SALINITY_COLORMAP);
colorbar.setValueRange(meanSalt - stdSalt, meanSalt + (stdSalt / 2));
GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
graphicsContext.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
PixelWriter pixelWriter = graphicsContext.getPixelWriter();
for (int x = 0; x < canvas.getWidth(); ++x) {
for (int y = 0; y < canvas.getHeight(); ++y) {
GeoCoordinate coordinate = getMapCoordinates(x, y);
if (model.isOverWater(coordinate)) {
float salt = model.computeSalinity(coordinate, depth, t);
pixelWriter.setColor(x, y, colorbar.getColor(salt));
}
}
}
}
This is the code that runs every frame, but even a simpler version like the one below still runs at 30 fps.
private void drawHeatMapBenchmark(int depth, float t) {
GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
graphicsContext.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
PixelWriter pixelWriter = graphicsContext.getPixelWriter();
for (int x = 0; x < canvas.getWidth(); ++x) {
for (int y = 0; y < canvas.getHeight(); ++y) {
pixelWriter.setColor(x, y, Color.gray(Math.random()));
}
}
}
Anyone knows a better approach to this? I'm not familiar with computer graphics, thank you.
You are doing all this on the (single) JavaFX application thread. It might help if you first render your heat map into an image which you then draw onto the canvas because for your particular case it seems to be very simple to do all the image rendering on parallel threads which should speed up the whole process.

Faster way to redraw a bitmap in android?

I'm processing an image for OCR, and I need to change the color of a bunch of pixels in a bitmap. Is there a faster method than setPixel and getPixel? Currently I'm just doing a for loop with a method that checks the input vs a bunch of RGB values and returns true if there's a match. Thank you very much!
Bitmap img = myImage.copy(Bitmap.Config.ARGB_8888, true);;
for (int w = 0; w < img.getWidth(); w++) {
for (int h = 0; h < img.getHeight(); h++) {
int value = img.getPixel(w, h);
if (filter(value)) {
img.setPixel(w, h, Color.rgb(0, 0, 0));
} else img.setPixel(w, h, Color.rgb(255, 255, 255));
}
}
Just wanted to follow up and post code for if anyone finds this via search.
My code in the question was taking 3.4s on average, the code below using Gabe's advice is taking under 200ms. I also added a length variable because I read not calling array.length() every iteration could improve performance, but in testing there doesn't seem to be much of a benefit
int width = img.getWidth();
int height = img.getHeight();
int length = width * height;
int[] pixels = new int[width*height];
img.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 0; i < length; i++) {
if (filter(pixels[i])) {
pixels[i] = Color.rgb(0, 0, 0);
} else pixels[i] = Color.rgb(255, 255, 255);
}
img.setPixels(pixels, 0, width, 0, 0, width, height);
You could always try to break up your image into quadrants/ a grid and assign each quadrant a separate thread.
I normally handle images with OpenCV on Jni. It is much faster than handling on Java. If you are not familliar with JNI, please reference this link. What is JNI Graphics or how to use it?
You can also divide image and then process with multi-threading!

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.

Create image from 2D Color Array

I have an array called image[][] and i want to create a BufferedImage out of this so I can have the player store it in a file.
// Initialize Color[][] however you were already doing so.
Color[][] image;
// Initialize BufferedImage, assuming Color[][] is already properly populated.
BufferedImage bufferedImage = new BufferedImage(image.length, image[0].length,
BufferedImage.TYPE_INT_RGB);
// Set each pixel of the BufferedImage to the color from the Color[][].
for (int x = 0; x < image.length; x++) {
for (int y = 0; y < image[x].length; y++) {
bufferedImage.setRGB(x, y, image[x][y].getRGB());
}
}
This is a straightforward way of creating (and potentially storing) an image, if that's what you're trying to get at. However, this is not efficient by any means. Try it with a larger image and you'll see a noticeable speed difference.

Fast gathering image on screen and reading the pixels

I'm trying to get a small section of image on the screen and read any pixel to compare the other pixels.The code to get screen image is:
Rectangle captureSize = new Rectangle(x, y, height, width);
BufferedImage image = robot.createScreenCapture(captureSize);
And, to read pixel by pixel I used
for (int y = 0; y < image.getHeight(); y = y + 1) {
for (int x = 0; x < image.getWidth(); x = x + 1) {
color = image.getRGB(x, y);
// Some methods etc
{
{
However, when I ran it I was shocked. Because createScreenCapture took about 40 ms and using getRGB of each pixel took around 350 ms which is very inefficient to create an application for 60 fps. By the way, my image is 800x400 pixels size. I didn't try
rgbArray = image.getRGB(startX, startY, w, h, rgbArray,offset, scansize) ;
method because I don't know how efficient it is and to reorder my code would be a bit difficult. So, any help would be appreciated.
Use
rgbArray = image.getRGB(startX, startY, w, h, rgbArray,offset, scansize) ;
It will be much faster to read the pixel values from the array than to do the method call to get each pixel value, and the single call to getRGB to fetch the array is not slow.

Categories