0

I'm currently working on a dynamic Animation Loader for Characters in a game and for that I'm in need of detecting if the current frame is completely blank in order to stop loading more sprites. This is what I'm currently using to find out if the current image is blank:

public static boolean isBlankImage(BufferedImage b) {
    byte[] pixels1 = getPixels(b);
    byte[] pixels2 = getPixels(getBlankImage(b.getWidth(), b.getHeight()));

    return Arrays.equals(pixels1, pixels2);
}

private static BufferedImage getBlankImage(int width, int height) {
    return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}

private static byte[] getPixels(BufferedImage b) {
    byte[] pixels = ((DataBufferByte) b.getRaster().getDataBuffer()).getData();
    return pixels;
}

However, as soon as I run it, I get this annoying error:

Exception in thread "Thread-0" java.lang.ClassCastException: 
    java.awt.image.DataBufferInt cannot be cast to java.awt.image.DataBufferByte

I've tried switching the casting type but all I get in return is:

Exception in thread "Thread-0" java.lang.ClassCastException: 
    java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt

I've searched all over the place for an answer to no avail, so here's my question: Is there a better functional way to check if an image is fully transparent ?

Any help will be greatly appreciated.

2 Answers2

1

The blank image's DataBuffer is indeed an instance of DataBufferInt while your original image has a buffer of type DataBufferByte. You should create your empty image based on the type of the image to compare with:

private static BufferedImage getBlankImage(int width, int height, int type) {
    return new BufferedImage(width, height, type);
}

and call it this way:

getBlankImage(b.getWidth(), b.getHeight(), b.getType())

Notice that in terms of performance and memory usage it may be better to create the empty image only once (or once for each image type which may occur). Probably the image type and size are constant and written wherever the actual images are created.

Now you have a proper empty image and may test its equality as in Is there a simple way to compare BufferedImage instances?:

public static boolean compareImages(BufferedImage imgA, BufferedImage imgB) {
  int width  = imgA.getWidth();
  int height = imgA.getHeight();

  // Loop over every pixel.
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      // Compare the pixels for equality.
      if (imgA.getRGB(x, y) != imgB.getRGB(x, y)) {
        return false;
      }
    }
  }

  return true;
}
Hero Wanders
  • 3,237
  • 1
  • 10
  • 14
1

The method must be return a byte array, you are trying convert a DataBuffer in a DataBufferByte. I have changed the name getPixels to getByteArray. Since it is not the same. Try this:

private static byte[] getByteArray(BufferedImage img) {
  byte[] imageInByte = null;
  String format = "jpeg"; //Needs a image TYPE
  try {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(img, format, baos);
    baos.flush();
    imageInByte = baos.toByteArray();
    baos.close();
  } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
  return imageInByte;
}