简体   繁体   English

接收到的包含 bitmap 的字节数组返回 null

[英]Received byte array containing bitmap returns null

I've been trying to send an image from one device to another using the BluetoothChat sample from Google.我一直在尝试使用 Google 的 BluetoothChat 示例将图像从一台设备发送到另一台设备。 I can send string value from device to device but I'm having problems sending images.我可以从一个设备向另一个设备发送字符串值,但我在发送图像时遇到了问题。 I have two classes handling the receiving and sending of data.我有两个类处理数据的接收和发送。

For sending images, I convert the image path to bitmap then convert it to byte[] and pass that to the utility class, same as the BluetoothChat sample but with increased buffer size (1024 default, changed it to 8192).为了发送图像,我将图像路径转换为 bitmap,然后将其转换为 byte[],并将其传递给实用程序 class,与 BluetoothChat 示例相同,但缓冲区大小增加(默认为 1024,将其更改为 8192)。 My code for the BluetoothSend class that sends data to the utility class is this,我的 BluetoothSend class 将数据发送到实用程序 class 的代码是这样的,

send.setOnClickListener(view -> {
            Bitmap bitmap = BitmapFactory.decodeFile(filePath);

            int width = bitmap.getRowBytes();
            int height = bitmap.getHeight();
            int bmpSize = width * height;

            ByteBuffer byteBuffer = ByteBuffer.allocate(bmpSize);
            bitmap.copyPixelsToBuffer(byteBuffer);

            byte[] byteArray = byteBuffer.array();
            sendUtils.write(byteArray);

            bitmap.recycle();
    });

This is the utility class that handles the sending and receiving of data,这是处理数据发送和接收的实用程序 class,

/**
 * This thread runs during a connection with a remote device.
 * It handles all incoming and outgoing transmissions.
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket bluetoothsocket;
    private final InputStream inputStream;
    private final OutputStream outputStream;

    public ConnectedThread(BluetoothSocket socket) {
        bluetoothsocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        try {
            tmpIn = bluetoothsocket.getInputStream();
            tmpOut = bluetoothsocket.getOutputStream();
        } catch (IOException e) {
            Log.e("ConnectedThrd->Cons", "Socket not created.");
            e.printStackTrace();
        }
        inputStream = tmpIn;
        outputStream = tmpOut;
    }

    public void run() {
        byte[] buffer = new byte[8192]; //1024 original
        int bytes;

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                try {
                    bytes = inputStream.read(buffer);
                    // Send the obtained bytes to the UI Activity
                    handler.obtainMessage(BluetoothSend.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
                    handler.obtainMessage(BluetoothReceive.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
                } catch (NullPointerException n) {
                    Log.e("ConnectedThrd->Run", n.getMessage());
                }
            } catch (IOException e) {
                Log.e("ConnectedThrd->Run", "Connection Lost.", e);
                e.printStackTrace();
                connectionLost();
                break;
            }
        }
    }

    public void write(byte[] buffer) {
        try {
            try {
                outputStream.write(buffer);
                handler.obtainMessage(BluetoothSend.MESSAGE_WRITE, -1, -1, buffer)
                        .sendToTarget();
                handler.obtainMessage(BluetoothReceive.MESSAGE_WRITE, -1, -1, buffer)
                        .sendToTarget();
            } catch (NullPointerException n) {
                Log.e("ConnectedThrd->Write", "Bluetooth Socket is null: " + n.getMessage());
            }
        } catch (IOException e) {
            Log.e("ConnectedThread->Write", "Empty write stream.");
        }
    }

    public void cancel() {
        try {
            bluetoothsocket.close();
        } catch (IOException e) {
            Log.e("ConnectedThread->Cancel", "Failed to close socket.");
        }
    }
}

Lastly, on the BluetoothReceive class, I receive the data using a handler.最后,在 BluetoothReceive class 上,我使用处理程序接收数据。 Code for handler object is as follows,处理程序 object 的代码如下,

            case MESSAGE_READ:
                //Read message from sender
                byte[] bufferRead = (byte[]) message.obj;
                //bitmap decodedByte is null
                Bitmap decodedByte = BitmapFactory.decodeByteArray(bufferRead, 0, bufferRead.length);
                int height = decodedByte.getHeight();
                int width = decodedByte.getWidth();

                Bitmap.Config config = Bitmap.Config.valueOf(decodedByte.getConfig().name());
                Bitmap bitmap_tmp = Bitmap.createBitmap(width, height, config);
                ByteBuffer buffer = ByteBuffer.wrap(bufferRead);
                bitmap_tmp.copyPixelsFromBuffer(buffer);
                fileView.setImageBitmap(bitmap_tmp);
                break;

I seem to always get a null value when I try to convert the byte array received from the other device when I convert it to a bitmap so I can use it to display it in an ImageView.当我尝试转换从其他设备接收的字节数组时,我似乎总是得到一个 null 值,当我将它转换为 bitmap 时,我可以用它在 ImageView 中显示它。

What am I doing wrong?我究竟做错了什么?

As you said, you can pass strings.如您所说,您可以传递字符串。 You can convert bitmap to Base64 string format and sent it.您可以将 bitmap 转换为Base64字符串格式并发送。

Bitmap bitmap = BitmapFactory.decodeFile("filePath");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); 
byte[] bytes = baos.toByteArray();
String encodedImage = Base64.encodeToString(bytes, Base64.DEFAULT);

On receiving side, reverse it (String Base64 to image)在接收端,反转它(字符串Base64到图像)

byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
Bitmap decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM