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
How to use ImageObserver in Graphics method drawImage()
提问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 this
as the argument for the ImageObserver
will 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 BufferedImage
that 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 BufferedImage
s, File
s, and InputStream
s as input.
Thumbnailator 足够灵活,可以接受BufferedImage
s、File
s 和InputStream
s 作为输入。
Seeing your edit, I would suggest to change the Hitter
class, so that it will perform the resizing of the image in the constructor.
看到您的编辑,我建议更改Hitter
类,以便它在构造函数中执行图像大小的调整。
Since you are calling the drawHitter
method on each call from the Applet.drawImage
, the resize operation using Graphics.drawImage
is being called many times, even when the hitterWidth
and hitterHeight
are, for all intents and purposes, constants.
由于您drawHitter
在每次调用 时调用该方法Applet.drawImage
,因此会Graphics.drawImage
多次调用using 的调整大小操作,即使hitterWidth
和hitterHeight
出于所有意图和目的都是常量。
Resizing the Image
ahead of time, and drawing that pre-resized image in the drawHitter
method will be more efficient.
Image
提前调整大小,并在该drawHitter
方法中绘制预先调整大小的图像会更有效。