WritableRasterからDataBufferを取得して画像の比較
Total: 7008, Today: 1, Yesterday: 0
Posted by aterai at 
Last-modified: 
Summary
2つの画像からそれぞれピクセル配列を取得して比較を行い、完全に一致するピクセルのアルファ値を下げることで違いを強調表示します。
Screenshot

Advertisement
Source Code Examples
int w = iia.getIconWidth();
int h = iia.getIconHeight();
int[] pixelsA = getData(iia, w, h);
int[] pixelsB = getData(iib, w, h);
source = new MemoryImageSource(w, h, pixelsA, 0, w);
for (int i = 0; i < pixelsA.length; i++) {
  if (pixelsA[i] == pixelsB[i]) {
    pixelsA[i] = pixelsA[i] & 0x44_FF_FF_FF;
  }
}
// ...
private static int[] getData(Image img, int w, int h) {
  BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
  Graphics g = image.createGraphics();
  g.drawImage(img, 0, 0, null);
  g.dispose();
  // XXX?: return ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
  int[] pixels = new int[w * h];
  EventQueue systemEventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
  SecondaryLoop loop = systemEventQueue.createSecondaryLoop();
  Thread worker = new Thread(() -> {
    try {
      new PixelGrabber(image, 0, 0, w, h, pixels, 0, w).grabPixels();
    } catch (InterruptedException ex) {
      Thread.currentThread().interrupt();
    }
    loop.exit();
  });
  worker.start();
  loop.enter();
  return pixels;
}
View in GitHub: Java, KotlinDescription
上記のサンプルでは、以下の手順で同サイズの画像から、それぞれのピクセル配列を取得して比較を行っています。
- 画像ファイルから
ImageIO.read(...)でImageを取得 BufferedImage.TYPE_INT_RGBで作成したBufferedImageにImageをコピーBufferedImageからWritableRasterを取得WritableRasterからDataBufferを取得DataBufferをDataBufferIntにキャストしてDataBufferInt#getData()でintのピクセル配列を取得
- 比較結果は
MemoryImageSourceに格納しComponent#createImage(ImageProducer)メソッドでImageに変換 ImageIO.read(...)で取得したBufferedImageからgetRaster().getDataBuffer()でDataBufferを取り出すとDataBufferByteになる?getRaster().getDataBuffer().getData()でint配列を取得すると空になる?ため、代わりにPixelGrabberを使用するよう修正