【问题标题】:Send Java BufferedImage to Bitmap Android将 Java BufferedImage 发送到位图 Android
【发布时间】:2015-04-05 02:11:36
【问题描述】:

您好,我正在尝试通过 tcp 套接字将我在 Java 应用程序上的 BufferedImage 发送到 Android 设备。我目前从 BufferedImage 获取 byte[] 中的栅格,然后通过普通的 OutputStream 将其发送到设备。这工作正常,我在 Android 端得到了相同的字节数组。但是,当我调用 Bitmap.decodeByteArray() 时,我只得到空值。

这是我必须用 Java 发送图片的代码。 BufferedImage 的图像类型为 TYPE_4BYTE_ABGR

byte[] imgBytes =    ((DataBufferByte)msg.getImage().getData().getDataBuffer()).getData();

lineBytes = (String.valueOf(imgBytes.length) + '\n').getBytes();        
out.write(lineBytes);
out.write(imgBytes);
out.write((int)'\n');
out.flush();

我写的第一件事是图像的大小,所以我知道在 Android 上制作 byte[] 有多大。

这是我试图用来创建 Android 位图的代码。

currLine = readLine(in);
int imgSize = Integer.parseInt(currLine);
byte[] imgBytes = new byte[imgSize];
in.read(imgBytes);
BitmapFactory.Options imgOptions = new BitmapFactory.Options();
imgOptions.inPreferredConfig = Bitmap.Config.ARGB_4444;

Bitmap img = BitmapFactory.decodeByteArray(imgBytes, 0, imgSize, imgOptions);

字节可以正常到达。它们只是不适用于位图。

【问题讨论】:

  • 您可能不想解码数组,因为字节一开始就没有编码。它只是“原始”像素。您还需要传递高度和宽度以正确重建图像。尝试Bitmap.createBitmap 方法之一。

标签: java android bitmap bufferedimage


【解决方案1】:

详细说明我在评论中提出的建议:

从 Java/服务器端,发送图像的宽度和高度(如果您知道图像的类型始终为 TYPE_4BYTE_ABGR,则不需要其他任何内容):

BufferedImage image = msg.getImage();
byte[] imgBytes = ((DataBufferByte) image.getData().getDataBuffer()).getData();

// Using DataOutputStream for simplicity
DataOutputStream data = new DataOutputStream(out);

data.writeInt(image.getWidth());
data.writeInt(image.getHeight());
data.write(imgBytes);

data.flush();

现在您可以在服务器端或客户端将交错的 ABGR 字节数组转换为打包的 int ARGB,这并不重要。为简单起见,我将在 Android/客户端显示转换:

// Read image data
DataInputStream data = new DataInputStream(in);
int w = data.readInt();
int h = data.readInt();
byte[] imgBytes = new byte[w * h * 4]; // 4 byte ABGR
data.readFully(imgBytes);

// Convert 4 byte interleaved ABGR to int packed ARGB
int[] pixels = new int[w * h];
for (int i = 0; i < pixels.length; i++) {
    int byteIndex = i * 4;
    pixels[i] = 
            ((imgBytes[byteIndex    ] & 0xFF) << 24) 
          | ((imgBytes[byteIndex + 3] & 0xFF) << 16) 
          | ((imgBytes[byteIndex + 2] & 0xFF) <<  8) 
          |  (imgBytes[byteIndex + 1] & 0xFF);
} 

// Finally, create bitmap from packed int ARGB, using ARGB_8888
Bitmap bitmap = Bitmap.createBitmap(pixels, w, h, Bitmap.Config.ARGB_8888);

如果您真的想要ARGB_4444,您可以转换位图,但请注意,该常量在所有最新版本的 Android API 中均已弃用。

【讨论】:

  • 感谢您的回答,它清除了一些我很困惑的东西。这在整个时间都有效的意义上更有效。不幸的是,生成的图像根本不起作用。所有的颜色都完全消失了。我可以在图像中看到最终的形状,但我不认为这些变化工作正常,尽管我画了一些东西,看起来它们肯定是正确的。
  • 我通过将像素 for 循环内的索引更改为所有索引的 imgBytes[(i*4)] 来使其适用于红色和绿色,因为我们需要获取字节 4-7在像素 [1] 而不是 1-4 上。但是每当我拍一张带有蓝色的照片时,它就会完全损坏为黄色。我正在对字节值进行一些手动调试,但没有找到太多
  • 好的,现在可以工作了所以像素[i]的最终循环语句 = ((imgBytes[byteIndex] & 0xFF)
  • @TylerHelmuth 对错误感到抱歉!现在更新了示例代码,可以按预期工作。很高兴听到它有效!
  • @haraldK 你能帮我处理一下this吗?
【解决方案2】:

imgSize 应该是图像的大小。为什么不试试imgBytes.length

【讨论】:

    猜你喜欢
    • 2012-05-24
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多