【问题标题】:How to convert BufferedImage to an int[]?如何将 BufferedImage 转换为 int[]?
【发布时间】:2016-06-14 04:27:53
【问题描述】:

我正在寻找通过套接字发送具有 BufferedImage 的对象。 BufferedImage 是不可序列化的,所以需要转换成可序列化的数据类型,然后再返回。我在网上看了很多,byte[] 似乎只发送一个 BuffereImage,但我试图发送整个对象,所以我更倾向于 int[]。我以为我在几周前遇到了一个解释这个问题的答案,但经过 2.5 小时的搜索,我找不到它。我试过 Java Oracle,但很快就迷路了。

如果有更好的方法,请原谅我的无知,因为我并没有真正在套接字和 BufferedImage 操作方面做过很多工作。

【问题讨论】:

  • 你为什么不用byte[]
  • 因为我看到它被使用的大多数实例只是通过套接字发送一个抖动的图像,而不是整个对象......除非我完全错了
  • 为此使用 ImageIO,除非您非常非常确定要通过网络发送原始图像光栅数据。 (你不是,根据你的问题=)docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html
  • 您可以使用 ImageIO 类将 BufferedImage 转换为 PNG 图像(无损,支持透明度,具有一些无损压缩)。你应该可以用一两行代码来做到这一点。它还将保存图像尺寸等,而原始数组不会这样做。这就是 PNG 等图像格式的用途(图像的存储和传输)。
  • 您使用 ImageIO 将 BufferedImage 转换为您通过套接字发送的二进制数据(PNG 或其他)。然后,另一方面,您使用 ImageIO 将其转换回 BufferedImage

标签: java arrays sockets int bufferedimage


【解决方案1】:

BufferedImage 基本上是一个数组。像素存储到DataBuffer中,这是一个数组。

BufferedImage source = //...
switch ( source.getType() )
    {
    case BufferedImage.TYPE_BYTE_GRAY :
    case BufferedImage.TYPE_3BYTE_BGR :
    case BufferedImage.TYPE_4BYTE_ABGR :
        final byte[] bb = ((DataBufferByte)source.getRaster().getDataBuffer()).getData() ;
        //...
        break ;
    case BufferedImage.TYPE_USHORT_GRAY :
        final short[] sb = ((DataBufferUShort)source.getRaster().getDataBuffer()).getData() ;
        //...
        break ;
    case BufferedImage.TYPE_INT_RGB :
    case BufferedImage.TYPE_INT_BGR :
    case BufferedImage.TYPE_INT_ARGB :
        final int[] ib = ((DataBufferInt)source.getRaster().getDataBuffer()).getData() ;
        break ;
    // etc.
    }

您还需要发送图像尺寸以及通道数。

【讨论】:

  • 必须通过网络传输的大型数组(并且知道图像本身的大小)的缺点已经存在(与 PNG 压缩数据相比) cmets中提到。此外,像这样获取数据缓冲区数据会导致图像变得“不可追踪”(有时称为“非托管”),并且会显着降低该图像的绘制性能。除此之外,无论提问者想要的方法是否是最好的,这都是对该问题的合理回答......
  • 是的,我正在回答基本问题“将图像转换为 int[]”。是的,发送压缩数据会更快。
【解决方案2】:

以 PNG 格式发送图像:

// BufferedImage -> byte sequence
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, "PNG", baos);
byte[] imageData = baos.toByteArray();
// byte sequence -> BufferedImage
ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
BufferedImage img = ImageIO.read(bais);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-14
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 2013-09-26
    • 2017-12-15
    相关资源
    最近更新 更多