提供されるインタフェースは非常に不透明なため、初期の開発段階では、イメージのピクセルデータに直接アクセスする方法はありませんでした。開発者が難解で複雑な ImageConsumer インタフェースを積極的に学習すれば、データにアクセスすることは可能でした。このインタフェースは、イメージデコーダから画面へピクセルデータを交信するためにイメージサブシステムが使用するものです。しかし、ほとんどの開発者は、このデータを一般的なケースで取得する簡単な機構を望んでいました。
このニーズに応えるために、ユーティリティクラスが作成され、「位置 (x, y) のピクセルは何色か」を指定するだけで済ませたい場合に、開発者の代わりに ImageConsumer インタフェースを制御します。PixelGrabber クラスは、ピクセルの矩形領域をイメージソースから Java 整数配列にスナップショットを作成する機能を提供しました。
このクラスが提供するインタフェースで、次の 3 つの重要な機能が不足していました。
new PixelGrabber(Image img, int x, int y, int w, int h, boolean forceRGB) startGrabbing() abortGrabbing() getWidth() getHeight() getPixels() getColorModel()
元の形式で、未知の次元のイメージのピクセルをグラブするための新しい API の使用方法を示すサンプルコードを次に示します。
import java.awt.*;
import java.awt.image.*;
import java.applet.*;
public class GrabExample extends Applet implements Runnable {
Thread grab;
Image img;
PixelGrabber pg;
public void init() {
img = getImage(getDocumentBase(), "theImage.gif");
pg = new PixelGrabber(img, 0, 0, -1, -1, false);
// In reality, the init method shouldn't be kicking off
// heavyweight operations like an image download, but
// this demonstrates use of the asynchronous grabbing...
pg.startGrabbing();
}
public void start() {
grab = new Thread(this);
grab.start();
}
public synchronized void stop() {
grab.interrupt();
grab = null;
}
public synchronized void run() {
try {
pg.grabPixels();
repaint();
} catch (InterruptedException e) {
System.err.println("grab was interrupted");
return;
}
}
public void paint(Graphics g) {
// Display some pixel values
int status = pg.getStatus();
if ((status & ABORT) != 0) {
g.drawString("Image grab was aborted", 10, 100);
} else if ((status & ALLBITS) != 0) {
g.drawString("Image grab is complete", 10, 100);
} else if ((status & FRAMEBITS) != 0) {
g.drawString("Frame grab is complete", 10, 100);
} else if ((status & SOMEBITS) != 0) {
g.drawString("Image grab is under way", 10, 100);
}
if ((status & (WIDTH|ALLBITS|FRAMEBITS)) != 0) {
FontMetrics fm = g.getFontMetrics();
String caption = "First 3 pixels: ";
int x = 10;
int w = pg.getWidth();
Object pix = pg.getPixels();
ColorModel cm = pg.getColorModel();
g.drawString(caption, x, 50);
x += fm.stringWidth(caption);
if (pix instanceof byte[]) {
for (int i = 0; i < Math.min(3, w); i++) {
String s = Integer.toString(((byte[])pix)[i]&0xff, 16);
g.drawString(s, x, 50);
x += fm.stringWidth(s + " ");
}
} else {
for (int i = 0; i < Math.min(3, w); i++) {
String s = Integer.toString(((int[])pix)[i], 16);
g.drawString(s, x, 50);
x += fm.stringWidth(s + " ");
}
}
}
}
}