简体   繁体   中英

Setting raw data/byte array as a source of an ImageView

I have a Client-Server system where server is written in cpp and the client is written is Java (Android application).

The server reads an image from a local directory as an ifstream using read method. The reading process is done inside a loop, where the program reads parts of the image every time. Every time a part of the image is read, it's sent over a socket to the client that collects all the piece inside a byteBuffer and when all the bytes of the image are transfered to the client, the client attempts to turn that array of bytes (after using byteBuffer.array() method) into a Bitmap. This is where the problem begins - I've tried a few methods but it seems that I'm unable to turn this array of bytes into a Bitmap.

From what I understood, this byte array is probably a raw representation of the image, which can't be decodded using methods like BitmapFactory.decodeByteArray() since it wasn't encoded in the first place.

Ultimately, my question is - how can I proccess this array of bytes so that I'll be able to set the image as a source to an ImageView?

Note: I've already made sure that all the data is sent over the socket correctly and the pieces are collected in the right order.

Client code:

    byte[] image_bytes
    byte[] response_bytes;
    private void receive_image ( final String protocol, final int image_size, final int buffer_size)
    {
        if (image_size <= 0 || buffer_size <= 0)
            return;

        Thread image_receiver = new Thread(new Runnable() {
            @Override
            public void run() {
                ByteBuffer byteBuffer = ByteBuffer.allocate(image_size);
                byte[] buffer = new byte[buffer_size];
                int bytesReadSum = 0;
                try {
                    while (bytesReadSum != image_size) {
                        activeReader.read(buffer);
                        String message = new String(buffer);
                        if (TextUtils.substring(message, 0, 5len_of_protocol_number).equals(protocol)) {
                            int bytesToRead = Integer.parseInt(TextUtils.substring(message, 
                                    len_of_protocol_number, 
                                    len_of_protocol_number + len_of_data_len));

                            byteBuffer.put(Arrays.copyOfRange(buffer, 
                                    len_of_protocol_number + len_of_data_len, 
                                    bytesToRead + len_of_protocol_number + len_of_data_len));
                            bytesReadSum += bytesToRead;
                        } else {
                            response_bytes = null;
                            break;
                        }
                    }
                    if (bytesReadSum == image_size) {
                        image_bytes = byteBuffer.array();
                        if (image_bytes.length > 0)
                            response_bytes = image_bytes;
                        else
                            response_bytes = null;
                    }
                } catch (IOException e) {
                    response_bytes = null;
                }
            }
        });
        image_receiver.start();
        try {
            image_receiver.join();
        } catch (InterruptedException e) {
            response_bytes = null;
        }

        if (response_bytes != null) 
        {    
            final ImageView imageIV = (ImageView) findViewById(R.id.imageIV);
            File image_file = new File(Environment.getExternalStorageDirectory(), "image_file_jpg");
            try 
            {
                FileOutputStream stream = new FileOutputStream(image_file);
                stream.write(image_bytes);
            } 
            catch (FileNotFoundException e) 
            {
                e.printStackTrace();
            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            }
            //Here the method returns null
            final Bitmap image_bitmap = BitmapFactory.decodeFile(image_file.getAbsolutePath());
            main.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    imageIV.setImageBitmap(image_bitmap);
                    imageIV.invalidate();
                }
            }
        }
    }

Whenever you exchange data between two machines of different architectures via sockets you need to know the Endianness (big-endian/little-endian) of each machine. If different, you will need to convert bytes to correct the data. Perhaps that's your issue. Here's a link with sample code: Converting Little Endian to Big Endian . You should be able to easily find more articles explaining the concept.

It turned out that something was wrong with my sending protocol. After patching it up a bit it actually worked. Thanks for the help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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