How to save image without showing the window?

Started by jhovarie, February 14, 2018, 04:37:00

Previous topic - Next topic

jhovarie

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

spasi

Call glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE) before glfwCreateWindow.

jhovarie

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 :)