Hello I am trying to save image from lwjgl window. What I want is to save png image file but I dont whant to show the window.
because I am trying to make a library similar to imagemagick, opencv and GPUImage of IOS.
I am trying to use shader and LWJGL for graphics manipulation so I can modify the shader depends what I need. Now I am having problem with my code..
Main.java ------------------------------------------------------
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFWVidMode;
public class Main {
private int WINDOW_WIDTH = 640;
private int WINDOW_HEIGHT = 480;
public Main() {
File inputimagefile = new File("C:\\2y2.png");
try {
BufferedImage inputimg = ImageIO.read(inputimagefile);
WINDOW_WIDTH = inputimg.getWidth();
WINDOW_HEIGHT = inputimg.getHeight();
}catch(Exception ex) {
ex.printStackTrace();
}
if(!glfwInit()) {
System.err.println("GLFW Failed to initialized!");
System.exit(0);
}
long win = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Window", 0, 0);
GLFWVidMode videoMode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(win, ( videoMode.width() - WINDOW_WIDTH) /2, (videoMode.height() - WINDOW_HEIGHT)/2 );
glfwShowWindow(win);
glfwMakeContextCurrent(win);
GL.createCapabilities();
glEnable(GL_TEXTURE_2D);
float[] vertices = new float[] {
-1f, 1f, 0, //TOP LEFT 0
1f, 1f, 0, //TOP RIGHT 1
1f, -1f, 0, //BOTTOM RIGHT 2
-1f, -1f, 0, //BOTTOM LEFT 3
};
float[] texture = new float[] {
0,0,
1,0,
1,1,
0,1,
};
int[] indices = new int[] {
0,1,2,
2,3,0
};
Model model = new Model(vertices, texture, indices);
Shader shader = new Shader("shader");
//Texture tex = new Texture("./res/2x2.png");
Texture tex = new Texture(inputimagefile.toString());
int counterloop = 0;
while(!glfwWindowShouldClose(win)) {
if(glfwGetKey(win, GLFW_KEY_ESCAPE) == GL_TRUE){
glfwDestroyWindow(win);
break;
}
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
shader.bind();
//shader.setUniform("green",1);
shader.setUniform("sampler",0);
tex.bind(0);
model.render();
glfwSwapBuffers(win);
counterloop++;
if(counterloop == 1) {
SaveImage();
System.exit(0);
}
}
glfwTerminate();
}
private void SaveImage() {
//First off, we need to access the pixel data of the Display. Without this, we don't know what to save!
GL11.glReadBuffer(GL11.GL_FRONT);
int width = WINDOW_WIDTH;
int height= WINDOW_HEIGHT;
int bpp = 4; // Assuming a 32-bit display with a byte each for red, green, blue, and alpha.
ByteBuffer buffer = BufferUtils.createByteBuffer(width * height * bpp);
GL11.glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer );
//Save the screen image
File file = new File("output.png"); // The file to save to.
String format = "png"; // Example: "PNG" or "JPG"
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for(int x = 0; x < width; x++)
{
for(int y = 0; y < height; y++)
{
int i = (x + (width * y)) * bpp;
int r = buffer.get(i) & 0xFF;
int g = buffer.get(i + 1) & 0xFF;
int b = buffer.get(i + 2) & 0xFF;
image.setRGB(x, height - (y + 1), (0xFF << 24) | (r << 16) | (g << 8) | b);
}
}
try {
ImageIO.write(image, format, file);
} catch (IOException e) { e.printStackTrace(); }
}
public static void main(String[]args) {
new Main();
}
}
I did not include the code of Texture.java, Shader.java, Model.java and my vertex and fragment shader code here because, I think it is not needed.
Any help please.. I need to save png with out showing the window.
Related topic.. How to save image without showing the window using lwjgl version 2.4.9 http://forum.lwjgl.org/index.php?topic=6713.0
Call glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE) before glfwCreateWindow.
I tried it but it still show the windows and close automatically.. but your answer still help me to solve the issue.
What I id is add glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
before glfwCreateWindow
and I change the glfwShowWindow
to glfwHideWindow
and it works :)