Java 如何在 Graphics 方法 drawImage() 中使用 ImageObserver

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6638803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 08:30:25  来源:igfitidea点击:

How to use ImageObserver in Graphics method drawImage()

javaimageappletscaledraw

提问by Matias Grioni

The method I am trying to use is the: drawImage(image, int, int, int, int, ImageObserver) method so that i can scale my image, on all the examples i've seen the ImageObserver should be this, but this doesn't seem to work(i.e. the only methods i have seen is: drawImage(image, int, int, ImageObserver), don't know if this makes a difference).

我尝试使用的方法是: drawImage(image, int, int, int, int, ImageObserver) 方法,以便我可以缩放我的图像,在我见过的所有示例中,ImageObserver 应该是这样的,但这并不'似乎不起作用(即我见过的唯一方法是:drawImage(image, int, int, ImageObserver),不知道这是否有区别)。

Here is my main class that is the applet:

这是我的主要类,即小程序:

import java.applet.*;
import java.awt.*;

public class Main extends Applet implements Runnable{
    private Thread th;
    private Hitter hitter;

    //double buffering
    private Graphics dbg;
    private Image dbImage;

    public void init(){
        hitter = new Hitter(getImage(getCodeBase(), "Chitter.png"));
    }

    public void start(){
        th = new Thread(this);
        th.start();
    }

    public void stop(){
        th.stop();
    }

    public void update(Graphics g){
        if(dbImage == null){
            dbImage = createImage(this.getSize().width, this.getSize().width);
            dbg = dbImage.getGraphics();
        }

        dbg.setColor(getBackground());
        dbg.fillRect(0, 0, this.getSize().width, this.getSize().height);
        dbg.setColor(getForeground());
        paint(dbg);

        g.drawImage(dbImage, 0, 0, this);
    }

    public void paint(Graphics g){
        hitter.drawHitter(g);
    }

    public void run() {
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
        while(true){
            repaint();

            try{
                Thread.sleep(15);
            }catch(InterruptedException ex){}

            Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        }
    }

    public boolean mouseMove(Event e, int x, int y){
        hitter.move(x);

        return true;
    }

}

Here is the Hitter class:

这是 Hitter 类:

import java.awt.*;
import java.awt.image.ImageObserver;

public class Hitter{
    private int x, y;
    private Image hitter;
    private int hitterWidth = 50, hitterHeight = 10;
    private int appletsizeX = 500, appletsizeY = 500;

    Hitter(Image i){
        hitter = i;
        start();
    }

    public void drawHitter(Graphics g){
        g.drawImage(hitter, x, y, hitterWidth, hitterHeight, this);
    }

    public void move(int a){
        x = a;
    }

    public void start(){
        x = appletsizeX/2 - hitterWidth/2;
        y = 0;
    }
}

回答by coobird

Unless the class in which you are calling Graphics.drawImage(Image, int, int, int, int, ImageObserver)is an ImageObserver, using thisas the argument for the ImageObserverwill not work:

除非您在其中调用类Graphics.drawImage(Image, int, int, int, int, ImageObserver)ImageObserver使用this作为参数ImageObserver将不工作:

class MyClass {
  public void resizeImage() {
    Graphics g = getGraphicsObjectFromSomewhere();

    // The following line will not compile, as `MyClass` 
    // does not implement `ImageObserver`.
    g.drawImage(img, 0, 0, 50, 50, this);
  }
}

If you're resizing an image which does not require an ImageObserver(such as a BufferedImagethat already contains the image you want to resize), then you can just hand over a null:

如果您要调整不需要的图像大小ImageObserver(例如BufferedImage已经包含要调整大小的图像的图像),那么您只需交出一个null

// The image we want to resize
BufferedImage img = ImageIO.read("some-image.jpg");

// The Graphics object of the destination
// -- this will probably just be obtained from the destination image.
Graphics g = getGraphicsObjectFromSomewhere();

// Perform the resizing. Hand a `null` for the ImageObserver,
// as we don't need one.
g.drawImage(img, 0, 0, 50, 50, null);

That said, I'm going to throw in a little plug for my image resizing library Thumbnailator.

也就是说,我将为我的图像大小调整库Thumbnailator插入一个小插件。

If all that is required is to resize an image, it can be accomplished as simple as the following code:

如果所需的只是调整图像大小,则可以像以下代码一样简单地完成:

Thumbnails.of("path/to/image")
  .size(100, 100)
  .toFile("path/to/thumbnail");

Thumbnailator is flexible enough to accept BufferedImages, Files, and InputStreams as input.

Thumbnailator 足够灵活,可以接受BufferedImages、Files 和InputStreams 作为输入。



Seeing your edit, I would suggest to change the Hitterclass, so that it will perform the resizing of the image in the constructor.

看到您的编辑,我建议更改Hitter类,以便它在构造函数中执行图像大小的调整。

Since you are calling the drawHittermethod on each call from the Applet.drawImage, the resize operation using Graphics.drawImageis being called many times, even when the hitterWidthand hitterHeightare, for all intents and purposes, constants.

由于您drawHitter在每次调用 时调用该方法Applet.drawImage,因此会Graphics.drawImage多次调用using 的调整大小操作,即使hitterWidthhitterHeight出于所有意图和目的都是常量。

Resizing the Imageahead of time, and drawing that pre-resized image in the drawHittermethod will be more efficient.

Image提前调整大小,并在该drawHitter方法中绘制预先调整大小的图像会更有效。