如何在图形方式的drawImage使用ImageObserver的() [英] How to use ImageObserver in Graphics method drawImage()

查看:5113
本文介绍了如何在图形方式的drawImage使用ImageObserver的()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用的方法是:
的drawImage(图像,INT,INT,INT,INT,ImageObserver的)方法
这样我可以扩展我的形象,在所有的例子我见过的ImageObserver应该是这样的,但这似乎并没有工作(即我所看到的唯一方法是:
的drawImage(图像,INT,INT,ImageObserver的),不知道这是否有差别)。

下面是我的主类是小程序:

 进口java.applet中的*。
进口java.awt中的*。公共类主要扩展的Applet实现Runnable {
    私人主题日;
    私人挥臂击球手;    //双缓冲
    私有图形DBG;
    私人图像数据库图像;    公共无效的init(){
        击球手=新的击球(的getImage(得到codeBase的(),Chitter.png));
    }    公共无效的start(){
        日=新主题(本);
        th.start();
    }    公共无效停止(){
        th.stop();
    }    公共无效更新(图形G){
        如果(数据库图像== NULL){
            数据库图像=的createImage(this.getSize()宽度,this.getSize()的宽度。);
            DBG = dbImage.getGraphics();
        }        dbg.setColor(的getBackground());
        dbg.fillRect(0,0,this.getSize()宽度,this.getSize()高度。);
        dbg.setColor(getForeground());
        油漆(DBG);        g.drawImage(数据库图像,0,0,这一点);
    }    公共无效漆(图形G){
        hitter.drawHitter(G);
    }    公共无效的run(){
        。Thread.currentThread()setPriority(从Thread.MIN_PRIORITY);
        而(真){
            重绘();            尝试{
                视频下载(15);
            }赶上(InterruptedException的前){}            。Thread.currentThread()setPriority(Thread.MAX_PRIORITY);
        }
    }    公共布尔的mouseMove(事件E,诠释的x,int y)对{
        hitter.move(X);        返回true;
    }}

下面是挥臂类:

 进口java.awt中的*。
进口java.awt.image.ImageObserver中;公共类挥臂{
    私人诠释的x,y;
    私人形象击球手;
    私人INT hitterWidth = 50,hitterHeight = 10;
    私人INT appletsizeX = 500,appletsizeY = 500;    击球手(图一){
        击球手= I;
        开始();
    }    公共无效drawHitter(图形G){
        g.drawImage(安打,X,Y,hitterWidth,hitterHeight,这一点);
    }    公共无效移动(INT一个){
        X = A;
    }    公共无效的start(){
        X = appletsizeX / 2 - hitterWidth / 2;
        Y = 0;
    }
}


解决方案

除非类中,您呼叫的<一个href=\"http://download.oracle.com/javase/6/docs/api/java/awt/Graphics.html#drawImage%28java.awt.Image,%20int,%20int,%20int,%20int,%20java.awt.image.ImageObserver%29\"><$c$c>Graphics.drawImage(Image, INT,INT,INT,INT,ImageObserver的) 是一个<一个href=\"http://download.oracle.com/javase/6/docs/api/java/awt/image/ImageObserver.html\"><$c$c>ImageObserver,使用这个作为参数的的ImageObserver 将不起作用:

  MyClass类{
  公共无效resizeImage(){
    图形G = getGraphicsObjectFromSomewhere();    //下面一行将无法编译,因为`MyClass`
    //没有实现`ImageObserver`。
    g.drawImage(IMG,0,0,50,50,这一点);
  }
}

如果你调整它不需要的ImageObserver (如<的图像href=\"http://download.oracle.com/javase/6/docs/api/java/awt/image/BufferedImage.html\"><$c$c>BufferedImage已包含要调整图像大小),那么你可以交出一份

  //的图像,我们要调整
IMG的BufferedImage = ImageIO.read(一些-image.jpg文件);//目标的Graphics对象
// - 这将可能只是从目标图像得到的。
图形G = getGraphicsObjectFromSomewhere();//执行进行调整。手`null`为ImageObserver的,
//因为我们并不需要一个。
g.drawImage(IMG,0,0,50,50,NULL);

这是说,我会在一个小插件扔我的图像缩放库 Thumbnailator

如果所需要的一切都是为了调整图像大小,它可以实现简单,只要下面的code:

  Thumbnails.of(路径/要/图像)
  .size(100,100)
  .toFile(路径/要/缩略图);

Thumbnailator非常灵活,可以接受的BufferedImage S,文件 s和的InputStream 取值作为输入。


看到你的编辑,我会建议修改挥臂类,因此,它会在构造函数中进行图像的大小调整。

既然你正在呼吁每一通电话的 drawHitter 方法 Applet.drawImage ,使用大小调整操作 Graphics.drawImage 被多次调用,即使 hitterWidth hitterHeight 是,所有意图和目的,常量。

调整大小的图片时间提前,并绘制在 drawHitter 方法pre-调整后的图像会更有效。

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).

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:

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;
    }
}

解决方案

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:

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:

// 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.

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.


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

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.

Resizing the Image ahead of time, and drawing that pre-resized image in the drawHitter method will be more efficient.

这篇关于如何在图形方式的drawImage使用ImageObserver的()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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