简体   繁体   English

将原始数据/字节数组设置为ImageView的源

[英]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). 我有一个Client-Server系统,其中服务器是用cpp编写的,而客户端是使用Java(Android应用程序)编写的。

The server reads an image from a local directory as an ifstream using read method. 服务器使用读取方法从本地目录读取图像作为ifstream。 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. 每次读取图像的一部分时,图像都会通过套接字发送到客户端,该客户端收集byteBuffer内的所有片段,并且当图像的所有字节都传输到客户端时,客户端会尝试翻转该字节数组(使用byteBuffer.array()方法后)放入位图。 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. 据我了解,此字节数组可能是图像的原始表示形式,无法使用BitmapFactory.decodeByteArray()之类的方法进行解码,因为它不是一开始就被编码的。

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? 最终,我的问题是-如何处理此字节数组,以便能够将图像设置为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. 每当您通过套接字在具有不同体系结构的两台计算机之间交换数据时,您都需要了解每台计算机的字节序(big-endian / little-endian)。 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 . 这是带有示例代码的链接: 将Little Endian转换为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. 谢谢您的帮助。

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

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