How To convert awt image to jme image

Hi guys,



this might be a simple question but i dont get it.

how can i convert an awt image to jme image?



thanks in advance

freddy

ImageToAwt.convert(BufferedImage image, Format format, ByteBuffer buf)

ok that means i create the image out of the bytebuffer.

thanks :slight_smile:

Just beware of the time it takes to convert the image, I’ve found that it isn’t the most optimal process!

ImageToAwt.convert(BufferedImage image, Format format, ByteBuffer buf)


I'm confused. How does that method produce a jME Image? It doesn't return an Image object, so it must be putting the data into the ByteBuffer, right? How am I supposed to get a ByteBuffer to pass into the method?

(Sorry to resurrect the thread... I just really need to know. The documentation for ImageToAwt is really sparse.)

Way easier to use:

http://hub.jmonkeyengine.org/javadoc/com/jme3/texture/plugins/AWTLoader.html

1 Like

@pspeed: That worked perfectly! Thank you so much!



So the class to use when converting an AWT Image to a jME Image is com.jme3.texture.plugins.AWTLoader.



Here are the results of a simple test I did: a large plane with a texture I generated completely in code:



AWT Image to Texture 2



Here is the code itself:

[java]

// Create a plane.

Quad boardShape = new Quad(10.0f, 10.0f);

Geometry board = new Geometry(“Board”, boardShape);



// Create the board image.

BufferedImage boardImage = new BufferedImage(512, 512, BufferedImage.TYPE_INT_RGB);

Graphics2D boardGraphics = boardImage.createGraphics();



for(int y = 0; y < 16; y++)

{

for(int x = 0; x < 16; x++)

{

Color color = new Color(Color.HSBtoRGB((float)(x + y) / 32f, 1.0f, 1.0f));

boardGraphics.setColor(color);

boardGraphics.fillRect((x * 32) - 1, (y * 32) - 1, 30, 30);

}

}



Image image = new AWTLoader().load(boardImage, false);

Texture2D boardTexture = new Texture2D(image);



Material material = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

material.setTexture(“ColorMap”, boardTexture);



board.setMaterial(material);



rootNode.attachChild(board);

[/java]



NOTE: Because the image data must be copied from the AWT Image into the jME Image, this process is slow. This is not something you should do every frame. If you plan to use this method, generate the Image once at the beginning of the game (when all the assets are being loaded). At the least, make sure you only re-generate the image when it changes.

This is good, but what if I want to make a BufferedImage from a Texture2D ?



eg: which I recorded from the screen somewhere or from a NiftyProcessor like below. I know about the ImageToAwt but it seems didn’t work anymore and I don’t know why:



Here is a modified TestNiftyToMesh :



[java]public class TestNiftyToMesh extends SimpleApplication {



private Nifty nifty;



public static void main(String[] args) {

TestNiftyToMesh app = new TestNiftyToMesh();

app.start();

}

Texture2D tex, depthTex;

private boolean needCapture = false;



public void simpleInitApp() {

ViewPort niftyView = renderManager.createPreView(“NiftyView”, new Camera(1024, 768));

niftyView.setClearFlags(true, true, true);

NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,

inputManager,

audioRenderer,

niftyView);

nifty = niftyDisplay.getNifty();

nifty.fromXml(“all/intro.xml”, “start”);

niftyView.addProcessor(niftyDisplay);



Texture2D depthTex = new Texture2D(1024, 768, Format.Depth);

FrameBuffer fb = new FrameBuffer(1024, 768, 1);

fb.setDepthTexture(depthTex);



tex = new Texture2D(1024, 768, Format.RGBA8);

tex.setMinFilter(MinFilter.Trilinear);

tex.setMagFilter(MagFilter.Bilinear);



fb.setColorTexture(tex);

niftyView.setClearFlags(true, true, true);

niftyView.setOutputFrameBuffer(fb);



Box b = new Box(Vector3f.ZERO, 1, 1, 1);

Geometry geom = new Geometry(“Box”, b);

Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setTexture(“ColorMap”, tex);

geom.setMaterial(mat);

rootNode.attachChild(geom);



// Input



inputManager.addMapping(“capture”,

new KeyTrigger(KeyInput.KEY_SPACE));



// Test multiple listeners per mapping

inputManager.addListener(actionListener, “capture”);

}



BufferedImage textureToImage(Texture tex) {

Image img = tex.getImage();

return ImageToAwt.convert(img, false, false, 0);

}

int count = 0;



@Override

public void simpleUpdate(float tpf) {

super.simpleUpdate(tpf);



if (needCapture) {

//ScreenCaptureHelper sch = new ScreenCaptureHelper(this.cam, boxGeom, this.renderManager);

//sch.captureScreen();

BufferedImage img = textureToImage(tex);

saveImage(img, “F:/TestImage/Thumb” + count + “.png”, “png”);

needCapture = false;

}

}

private ActionListener actionListener = new ActionListener() {



public void onAction(String name, boolean pressed, float tpf) {

if (name.equals(“capture”) && pressed) {

needCapture = true;

}

}

};



public static void saveImage(BufferedImage image, String path, String format) {

File f = new File(path);

try {

// png is an image format (like gif or jpg)

ImageIO.write(image, format, f);

} catch (IOException ex) {

ex.printStackTrace();

}

}

}[/java]

Here is the exception:



[java]java.lang.NullPointerException

at jme3tools.converters.ImageToAwt.convert(ImageToAwt.java:383)

at jme3test.niftygui.TestNiftyToMesh.textureToImage(TestNiftyToMesh.java:109)

at jme3test.niftygui.TestNiftyToMesh.simpleUpdate(TestNiftyToMesh.java:120)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:258)[/java]



which because



[java] ByteBuffer buf = image.getData(0);

buf.order(ByteOrder.LITTLE_ENDIAN);[/java]



image at that time was null???

Of course, tex is only a placeholder, the image of it is only present in the graficcard.

@Empire Phoenix :

So do you know how I can do such a job : convert a screenshot into a BufferedImage ?

Can anyone explain to me how in the example above:

when a Texture set to Material, it show something on the screen

but when I want to get a Image from it, its Image (still null)… not really, but the Image’s data was a ArrayList has (0) children?

it’s confused?

Your graphics card is like a mini computer inside your computer. It has its own memory and everything. When you create and fill a texture on the GPU, it does not exist in your computer’s memory without additional effort. It only exists on the graphics card.

1 Like

It’s clear, but how about convert a screenshot, in the form of Texture2D or something else into a BufferedImage ? My last goal is to Save a nifty screen or a normal 3d screen into .png file… Is it true that we can’t do it in JME3???

http://hub.jmonkeyengine.org/javadoc/com/jme3/app/state/ScreenshotAppState.html