【问题标题】:Checking if an image is blank in Java检查Java中的图像是否为空白
【发布时间】:2018-09-03 00:07:26
【问题描述】:

我目前正在为游戏中的角色开发动态动画加载器,为此我需要检测当前帧是否完全空白以停止加载更多精灵。 这是我目前用来确定当前图像是否为空白的:

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

但是,一旦我运行它,我就会收到这个烦人的错误:

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

我尝试过切换投射类型,但得到的回报是:

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

我到处寻找答案都无济于事,所以这是我的问题:是否有更好的功能性方法来检查图像是否完全透明?

任何帮助将不胜感激。

【问题讨论】:

  • 什么是“空”图像?全白的东西,100% 透明的东西?
  • 谢谢@AndrewThompson,我会改变的。
  • @Kwright02。后者(正如对问题的编辑中所阐明的那样)。

标签: java image classcastexception


【解决方案1】:

该方法必须返回一个字节数组,您正在尝试将 DataBuffer 转换为 DataBufferByte。 我已将名称 getPixels 更改为 getByteArray。既然不一样。 试试这个:

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

【讨论】:

    【解决方案2】:

    空白图像的DataBuffer 确实是DataBufferInt 的一个实例,而您的原始图像具有DataBufferByte 类型的缓冲区。 您应该根据要比较的图像类型创建空图像:

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

    这样称呼它:

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

    请注意,就性能和内存使用而言,最好只创建一次空图像(或为可能出现的每种图像类型创建一次)。 可能图像类型和大小是恒定的,并写入实际图像创建的任何位置。

    现在你有一个正确的空图像,可以像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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      相关资源
      最近更新 更多