<p>To make it a more complete example, let's also consider loading a texture from a <code>BufferedImage</code> as well.</p>

<p>First let's assume:</p>

<pre><code>int texture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, texture);
</code></pre>

<p>First we need to load an image. For this we can use <code>ImageIO.read()</code>. Then we put all the pixels from the <code>BufferedImage</code> into a <code>ByteBuffer</code>.</p>

<pre><code>BufferedImage image = ImageIO.read(new File("image.png"));
int width = image.getWidth(), height = image.getHeight();

int[] pixels = new int[width * height];
image.getRGB(0, 0, width, height, pixels, 0, width);

ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 4); // 4 because RGBA

for(int y = 0; y &lt; height; ++y) {
    for(int x = 0; x &lt; width; ++x) {
        int pixel = pixels[x + y * width];
        buffer.put((byte) ((pixel &gt;&gt; 16) &amp; 0xFF));
        buffer.put((byte) ((pixel &gt;&gt; 8) &amp; 0xFF));
        buffer.put((byte) (pixel &amp; 0xFF));
        buffer.put((byte) ((pixel &gt;&gt; 24) &amp; 0xFF));
    }
}

buffer.flip();

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
</code></pre>

<p>Before we go ahead and call <code>glGetTexImage()</code> lets assume that the only thing we have is the texture name (<code>texture</code>). Thus we consider that we don't know the size or format of the texture. We can get all this by doing:</p>

<pre><code>int format = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT);
int width = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH);
int height = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT);
</code></pre>

<p>Using that information we again create a <code>ByteBuffer</code> as well as a <code>BufferedImage</code>. Reading the pixels from the <code>ByteBuffer</code> and placing them on the <code>BufferedImage</code>.</p>

<pre><code>int channels = 4;
if (format == GL_RGB)
    channels = 3;

ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * channels);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

glGetTexImage(GL_TEXTURE_2D, 0, format, GL_UNSIGNED_BYTE, buffer);

for (int x = 0; x &lt; width; ++x) {
    for (int y = 0; y &lt; height; ++y) {
        int i = (x + y * width) * channels;

        int r = buffer.get(i) &amp; 0xFF;
        int g = buffer.get(i + 1) &amp; 0xFF;
        int b = buffer.get(i + 2) &amp; 0xFF;
        int a = 255;
        if (channels == 4)
            a = buffer.get(i + 3) &amp; 0xFF;

        image.setRGB(x, y, (a &lt;&lt; 24) | (r &lt;&lt; 16) | (g &lt;&lt; 8) | b);
    }
}
</code></pre>

<p>Now go ahead and save that <code>BufferedImage</code> to a file.</p>

<pre><code>ImageIO.write(image, "PNG", new File("out.png"));
</code></pre>

<p>Last but not least, you can get rid of all those <code>GL11.</code> prefixes, by statically importing <code>GL11</code>. You do that by doing:</p>

<pre><code>import static org.lwjgl.opengl.GL11.*;
</code></pre>

CC BY-SA 3.0
2017-03-31T01:56:23.087Z
2017-03-31T03:09:59.420Z
2017-03-31T03:09:59.420Z
vallentin
<p>I have got a texture ID and would like to retrieve its data. The data should be stored in a <code>BufferedImage</code> for future use. I am using the LWJGL library in Java, so if there are some library-specific shortcuts I'd like to use them.</p>

<p>My naive approach is to first fill a buffer with the image data and then pass it to the image.</p>

<pre><code>int id = ...;
IntBuffer buff = BufferUtils.createIntBuffer(1024*512*4);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
System.out.println(buff.remaining());
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buff);
System.out.println(buff.remaining());
buff.flip();
buff.rewind();
System.out.println(buff.remaining());
// Somehow create a BufferedImage from buff here
</code></pre>

<p>I don't know why, but the first and to <code>buff.remaining()</code> return the same value, indicating that nothing has been written which should not be the case.</p>

<opengl><image>
LWJGL/OpenGL get BufferedImage from texture ID
piegames
# LWJGL/OpenGL get BufferedImage from texture ID

(Asked by: username_0 on 2017-03-30)

I have got a texture ID and would like to retrieve its data. The data should be stored in a BufferedImage for future use. I am using the LWJGL library in Java, so if there are some library-specific shortcuts I'd like to use them.
My naive approach is to first fill a buffer with the image data and then pass it to the image.
int id = ...;
IntBuffer buff = BufferUtils.createIntBuffer(1024*512*4);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
System.out.println(buff.remaining());
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, buff);
System.out.println(buff.remaining());
buff.flip();
buff.rewind();
System.out.println(buff.remaining());
// Somehow create a BufferedImage from buff here

I don't know why, but the first and to buff.remaining() return the same value, indicating that nothing has been written which should not be the case.

**Tags:** opengl, image

---

## 1 answers

### Answer by username_1 on 2017-03-31. Score: 5 | Accepted answer

To make it a more complete example, let's also consider loading a texture from a BufferedImage as well.
First let's assume:
int texture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, texture);

First we need to load an image. For this we can use ImageIO.read(). Then we put all the pixels from the BufferedImage into a ByteBuffer.
BufferedImage image = ImageIO.read(new File("image.png"));
int width = image.getWidth(), height = image.getHeight();

int[] pixels = new int[width * height];
image.getRGB(0, 0, width, height, pixels, 0, width);

ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * 4); // 4 because RGBA

for(int y = 0; y < height; ++y) {
    for(int x = 0; x < width; ++x) {
        int pixel = pixels[x + y * width];
        buffer.put((byte) ((pixel >> 16) & 0xFF));
        buffer.put((byte) ((pixel >> 8) & 0xFF));
        buffer.put((byte) (pixel & 0xFF));
        buffer.put((byte) ((pixel >> 24) & 0xFF));
    }
}

buffer.flip();

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

Before we go ahead and call glGetTexImage() lets assume that the only thing we have is the texture name (texture). Thus we consider that we don't know the size or format of the texture. We can get all this by doing:
int format = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT);
int width = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH);
int height = glGetTexLevelParameteri(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT);

Using that information we again create a ByteBuffer as well as a BufferedImage. Reading the pixels from the ByteBuffer and placing them on the BufferedImage.
int channels = 4;
if (format == GL_RGB)
    channels = 3;

ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * channels);
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

glGetTexImage(GL_TEXTURE_2D, 0, format, GL_UNSIGNED_BYTE, buffer);

for (int x = 0; x < width; ++x) {
    for (int y = 0; y < height; ++y) {
        int i = (x + y * width) * channels;

        int r = buffer.get(i) & 0xFF;
        int g = buffer.get(i + 1) & 0xFF;
        int b = buffer.get(i + 2) & 0xFF;
        int a = 255;
        if (channels == 4)
            a = buffer.get(i + 3) & 0xFF;

        image.setRGB(x, y, (a << 24) | (r << 16) | (g << 8) | b);
    }
}

Now go ahead and save that BufferedImage to a file.
ImageIO.write(image, "PNG", new File("out.png"));

Last but not least, you can get rid of all those GL11. prefixes, by statically importing GL11. You do that by doing:
import static org.lwjgl.opengl.GL11.*;


---

