Java – use graphics2d to draw images with sub-pixel precision
I'm currently trying to draw images on the screen at normal speed, just like in a video game
Unfortunately, due to the rate at which the image moves, some frames are the same because the image has not moved the entire pixel
Is there a way to provide floating-point values for graphics2d to draw images on the screen instead of int values?
At first I did this:
BufferedImage srcImage = sprite.getImage ( ); Position imagePosition = ... ; //Defined elsewhere g.drawImage ( srcImage,(int) imagePosition.getX(),(int) imagePosition.getY() );
This is of course the threshold, so the picture does not move between pixels, but jumps from one to the next
The next method is to set the paint color to texture, and then paint at the specified position Unfortunately, this produces incorrect results, showing tiling rather than correct antialiasing
g.setRenderingHint ( RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON ); BufferedImage srcImage = sprite.getImage ( ); g.setPaint ( new TexturePaint ( srcImage,new Rectangle2D.Float ( 0,srcImage.getWidth ( ),srcImage.getHeight ( ) ) ) ); AffineTransform xform = new AffineTransform ( ); xform.setToIdentity ( ); xform.translate ( onScreenPos.getX ( ),onScreenPos.getY ( ) ); g.transform ( xform ); g.fillRect(0,srcImage.getWidth(),srcImage.getHeight());
What can I do to achieve the desired effect of image sub-pixel rendering in Java?
Solution
You can use bufferedimage and affinetransform to draw to the buffered image, and then draw the buffered image to the component in the paint event
/* overrides the paint method */ @Override public void paint(Graphics g) { /* clear scene buffer */ g2d.clearRect(0,(int)width,(int)height); /* draw ball image to the memory image with transformed x/y double values */ AffineTransform t = new AffineTransform(); t.translate(ball.x,ball.y); // x/y set here,ball.x/y = double,ie: 10.33 t.scale(1,1); // scale = 1 g2d.drawImage(image,t,null); // draw the scene (double percision image) to the ui component g.drawImage(scene,this); }
See my complete example here: http://pastebin.com/hSAkYWqM