【问题标题】:Setting raw data/byte array as a source of an ImageView将原始数据/字节数组设置为 ImageView 的源
【发布时间】:2017-03-21 12:11:46
【问题描述】:

我有一个客户端-服务器系统,其中服务器是用 cpp 编写的,客户端是用 Java(Android 应用程序)编写的。

服务器使用 read 方法从本地目录读取图像作为 ifstream。 读取过程在循环中完成,程序每次都读取图像的一部分。每次读取图像的一部分时,它都会通过套接字发送到客户端,客户端收集 byteBuffer 中的所有片段,当图像的所有字节都传输到客户端时,客户端会尝试转换该字节数组(使用 byteBuffer.array() 方法后)进入位图。 这就是问题的开始——我尝试了几种方法,但似乎无法将这个字节数组转换为位图。

据我了解,这个字节数组可能是图像的原始表示,无法使用 BitmapFactory.decodeByteArray() 之类的方法对其进行解码,因为它一开始没有被编码。

最后,我的问题是 - 如何处理这个字节数组,以便能够将图像设置为 ImageView 的源?

注意:我已经确保所有数据都通过套接字正确发送,并且以正确的顺序收集碎片。

客户端代码:

    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();
                }
            }
        }
    }

【问题讨论】:

  • 发送什么样的图片? jpg文件和png文件应该没问题。作为测试,将字节数组保存到文件并检查您的 Android 应用程序是否可以显示该文件。相同的文件大小? bytearray.length 和发送的文件大小一样吗?
  • I've already made sure that all the data is sent over the socket correctly。请说出你是怎么做到的。
  • how can I proccess this array of bytes。您不需要处理或转换字节。
  • client that collects all the piece inside a byteBuffer。为什么不显示您的代码?
  • Setting raw data/byte array as a source of an ImageView。你的意思是“一个字节数组,包含一个 jpg 文件,作为位图的源”。

标签: java android image bitmap bitmapfactory


【解决方案1】:

每当您通过套接字在不同架构的两台机器之间交换数据时,您都需要知道每台机器的字节序(大端/小端)。如果不同,您将需要转换字节以更正数据。也许那是你的问题。这是示例代码的链接:Converting Little Endian to Big Endian。您应该能够轻松找到更多解释该概念的文章。

【讨论】:

  • 感谢您的回答。老实说,我对 Endianness 主题不是很熟悉,如何检查每台机器的 Endianness?
  • 找出服务器是什么机器/操作系统,你应该能够确定它。这是另一个可能有帮助的链接:searchnetworking.techtarget.com/definition/…
【解决方案2】:

原来我的发送协议有问题。 稍微修补一下后,它确实起作用了。 感谢您的帮助。

【讨论】:

    猜你喜欢
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多