Drawing an image using sub-pixel level accuracy using Graphics2D

前端 未结 4 1234
北荒
北荒 2021-02-15 14:48

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 fram

4条回答
  •  清酒与你
    2021-02-15 15:28

    I successfully solved my problem after doing something like lawrencealan proposed.

    Originally, I had the following code, where g is transformed to a 16:9 coordinate system before the method is called:

    private void drawStar(Graphics2D g, Star s) {
    
        double radius = s.getRadius();
        double x = s.getX() - radius;
        double y = s.getY() - radius;
        double width = radius*2;
        double height = radius*2;
    
        try {
    
            BufferedImage image = ImageIO.read(this.getClass().getResource("/images/star.png"));
            g.drawImage(image, (int)x, (int)y, (int)width, (int)height, this);
    
        } catch (IOException ex) {
            Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
        }
    
    }
    

    However, as noted by the questioner Kaushik Shankar, turning the double positions into integers makes the image "jump" around, and turning the double dimensions into integers makes it scale "jumpy" (why the hell does g.drawImage not accept doubles?!). What I found working for me was the following:

    private void drawStar(Graphics2D g, Star s) {
    
        AffineTransform originalTransform = g.getTransform();
    
        double radius = s.getRadius();
        double x = s.getX() - radius;
        double y = s.getY() - radius;
        double width = radius*2;
        double height = radius*2;
    
        try {
    
            BufferedImage image = ImageIO.read(this.getClass().getResource("/images/star.png"));
    
            g.translate(x, y);
            g.scale(width/image.getWidth(), height/image.getHeight());
    
            g.drawImage(image, 0, 0, this);
    
        } catch (IOException ex) {
            Logger.getLogger(View.class.getName()).log(Level.SEVERE, null, ex);
        }
    
        g.setTransform(originalTransform);
    
    }
    

    Seems like a stupid way of doing it though.

提交回复
热议问题