概要

2つの画像からそれぞれピクセル配列を取得して比較を行い、完全に一致するピクセルのアルファ値を下げることで違いを強調表示します。

サンプルコード

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, Kotlin

解説

上記のサンプルでは、以下の手順で同サイズの画像から、それぞれのピクセル配列を取得して比較を行っています。

  1. 画像ファイルからImageIO.read(...)Imageを取得
  2. BufferedImage.TYPE_INT_RGBで作成したBufferedImageImageをコピー
  3. BufferedImageからWritableRasterを取得
  4. WritableRasterからDataBufferを取得
  5. DataBufferDataBufferIntにキャストしてDataBufferInt#getData()intのピクセル配列を取得
  • 比較結果はMemoryImageSourceに格納しComponent#createImage(ImageProducer)メソッドでImageに変換
  • ImageIO.read(...)で取得したBufferedImageからgetRaster().getDataBuffer()DataBufferを取り出すとDataBufferByteになる?
  • getRaster().getDataBuffer().getData()int配列を取得すると空になる?ため、代わりにPixelGrabberを使用するよう修正

参考リンク

コメント