I have a Graphics2D object obtained from the BufferStrategy that I am drawing to. If I want to take the image data from the Graphics2D and store it off in a BufferedImage somewhere (say for a screenshot, or something like that), how would I go about doing that?
Thanks.
java.awt.Robot may work - I havn’t tried it.
Another solution, is to write your own Composite class, that, instead of doing a Composite with the destination pixels, writes the destination pixel to a BufferedImage.
Something like :-
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.awt.event.*;
public class ScreenCapture implements Composite, CompositeContext
{
private BufferedImage screenShot;
private ColorModel screenColorModel;
private ScreenCapture()
{
}
public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints)
{
screenColorModel = dstColorModel;
return this;
}
public void compose(Raster src, Raster dstIn, WritableRaster dstOut)
{
screenShot = new BufferedImage(screenColorModel,dstOut,false,(Hashtable)null);
}
public void dispose()
{
}
public static BufferedImage screenShot(Graphics2D g2d, Rectangle bounds)
{
Composite oldComposite = g2d.getComposite();
ScreenCapture ssc = new ScreenCapture();
g2d.setComposite(ssc);
g2d.fillRect(bounds.x,bounds.y,bounds.width,bounds.height);
g2d.setComposite(oldComposite);
return ssc.screenShot;
}
public static void main(String [] args)
{
final Frame f = new Frame();
f.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent ke)
{
if(ke.getKeyCode()==KeyEvent.VK_ESCAPE)
{
f.dispose();
}
}
});
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
gd.setFullScreenWindow(f);
gd.setDisplayMode(new DisplayMode(800,600,32,60));
f.createBufferStrategy(2);
BufferStrategy bs = f.getBufferStrategy();
Graphics2D g2d = (Graphics2D)bs.getDrawGraphics();
g2d.setColor(Color.black);
g2d.fillRect(0,0,800,600);
g2d.setColor(Color.red);
g2d.drawString("If the Capture worked, you should see this :-",50,50);
BufferedImage screenShot = ScreenCapture.screenShot(g2d,new Rectangle(0,0,800,600));
g2d.setColor(Color.black);
g2d.fillRect(0,0,800,600);
g2d.drawImage(screenShot,0,0,null);
bs.show();
}
}
:edit:
hahahahahaha, well… that idea should work.
But ofcourse like all good ideas… it doesn’t :-
java.lang.InternalError: not implemented yet
at sun.awt.windows.Win32OffScreenSurfaceData.getRaster(Win32OffScreenSurfaceData.java:249)
at sun.java2d.pipe.GeneralCompositePipe.renderPathTile(GeneralCompositePipe.java:82)
at sun.java2d.pipe.SpanShapeRenderer$Composite.renderBox(SpanShapeRenderer.java:42)
at sun.java2d.pipe.SpanShapeRenderer.renderRect(SpanShapeRenderer.java:171)
at sun.java2d.pipe.SpanShapeRenderer.fill(SpanShapeRenderer.java:122)
at sun.java2d.pipe.PixelToShapeConverter.fillRect(PixelToShapeConverter.java:44)
at sun.java2d.pipe.ValidatePipe.fillRect(ValidatePipe.java:58)
at sun.java2d.SunGraphics2D.fillRect(SunGraphics2D.java:2142)
at ScreenCapture.screenShot(ScreenCapture.java:35)
at ScreenCapture.main(ScreenCapture.java:67)
How easy it is to find bugs in Java2D =D
flibble!
yeah, this is a long-standing bug, fixed in 1.5 for accelerated offscreen surfaces, but not for the screen ones.