使用Graphics2D以亚像素级别的精度绘制图像 [英] Drawing an image using sub-pixel level accuracy using Graphics2D

查看:499
本文介绍了使用Graphics2D以亚像素级别的精度绘制图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试像在视频游戏中一样,以固定的速率在屏幕上绘制图像.

不幸的是,由于图像的移动速度,某些帧是相同的,因为图像尚未移动整个像素.

是否可以为Graphics2D提供float值以在屏幕上绘制图像而不是int值?

最初是我做的:

BufferedImage srcImage = sprite.getImage ( );
Position imagePosition = ... ; //Defined elsewhere
g.drawImage ( srcImage, (int) imagePosition.getX(), (int) imagePosition.getY() );

这当然是阈值,因此图片不会在像素之间移动,而是从一个跳到另一个.

下一个方法是将油漆颜色设置为纹理,然后在指定位置绘制.不幸的是,这产生了不正确的结果,显示的是平铺,而不是正确的抗锯齿.

g.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );

BufferedImage srcImage = sprite.getImage ( );

g.setPaint ( new TexturePaint ( srcImage, new Rectangle2D.Float ( 0, 0, srcImage.getWidth ( ), srcImage.getHeight ( ) ) ) );

AffineTransform xform = new AffineTransform ( );

xform.setToIdentity ( );
xform.translate ( onScreenPos.getX ( ), onScreenPos.getY ( ) );
g.transform ( xform );

g.fillRect(0, 0, srcImage.getWidth(), srcImage.getHeight());

我应该怎么做才能达到Java中图像的亚像素渲染的理想效果?

解决方案

您可以使用BufferedImageAffineTransform,绘制到缓冲的图像,然后在绘制事件中将缓冲的图像绘制到组件.

    /* overrides the paint method */
    @Override
    public void paint(Graphics g) {
        /* clear scene buffer */
        g2d.clearRect(0, 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, 0, 0, this);
    }

在此处查看我的完整示例: http://pastebin.com/hSAkYWqM

I am currently attempting to draw images on the screen at a regular rate like in a video game.

Unfortunately, because of the rate at which the image is moving, some frames are identical because the image has not yet moved a full pixel.

Is there a way to provide float values to Graphics2D for on-screen position to draw the image, rather than int values?

Initially here is what I had done:

BufferedImage srcImage = sprite.getImage ( );
Position imagePosition = ... ; //Defined elsewhere
g.drawImage ( srcImage, (int) imagePosition.getX(), (int) imagePosition.getY() );

This of course thresholds, so the picture doesn't move between pixels, but skips from one to the next.

The next method was to set the paint color to a texture instead and draw at a specified position. Unfortunately, this produced incorrect results that showed 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, 0, srcImage.getWidth ( ), srcImage.getHeight ( ) ) ) );

AffineTransform xform = new AffineTransform ( );

xform.setToIdentity ( );
xform.translate ( onScreenPos.getX ( ), onScreenPos.getY ( ) );
g.transform ( xform );

g.fillRect(0, 0, srcImage.getWidth(), srcImage.getHeight());

What should I do to achieve the desired effect of subpixel rendering of an Image in Java?

解决方案

You can use a BufferedImage and AffineTransform, draw to the buffered image, 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, 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, 0, 0, this);
    }

Check my full example here: http://pastebin.com/hSAkYWqM

这篇关于使用Graphics2D以亚像素级别的精度绘制图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆