挂起“compressToJpeg”

时间:2012-07-03 20:23:17

标签: android

查看以下所有3次修改

更新:将'read()'更改为'readFully()'并完成了一些工作。 'decodeByteArray()'不再返回null。写入卡片的jpeg实际上是一张完整的图像。图像仍未被绘制到我的视图中。如果需要,我会继续工作并发布另一个问题。

我正在编写一个视频流客户端程序,它从DataInputStream中获取图像。

因为服务器在这些图像上调用compressToJpeg(),我想我可以简单地从我的DataInputStream中获取字节数组,对其进行解码,然后将bitsmap从decodeByteArray()绘制到我的SurfaceView。不幸的是,该方法只让我使用decodeByteArray()返回null。

所以我添加了一个中间步骤。我创建了一个compressFrame()方法,它只从流中获取字节数组,创建一个新的YuvImage实例,并使用它来调用compressToJpeg()。但是,在运行时,此方法挂起在compressToJpeg 上,挂起我的客户端活动。没有FC弹出窗口,我的日志中没有错误。

我提供了调用问题方法的线程的run(),方法本身以及应用关闭之前打印的日志。

编辑:我还添加了ReceiverUtils.getFrame()以防万一。

@Override
public void run() {

    String fromServer = null;
    int jpgSize;
    byte[] buffer;
    byte[] jpgData;
    Bitmap image;
    ByteArrayOutputStream jpgBaos = null;

    while(isItOK && (receiver.textIn != null)){
        if(!holder.getSurface().isValid()){
            continue;
        }

        ReceiverUtils.init(holder);

        //Receive 'ready' flag from camcorder
        fromServer = ReceiverUtils.receiveText(receiver);

        while((fromServer != null)){

            Log.e("From server: ", fromServer); //logging here because of null pointers when done in Utils

            if(fromServer.startsWith("ANDROID_JPG_READY")){

                //Obtain size for byte array
                jpgSize = Integer.parseInt(fromServer.substring(18));
                Log.e("JPG SIZE", String.valueOf(jpgSize));

                //Create byte array of size jpgSize
                buffer = new byte[jpgSize];
                Log.e("BUFFER SIZE", String.valueOf(buffer.length));

                //Send flag and receive image data from camcorder
                ReceiverUtils.sendText(receiver, "ANDROID_JPG_SEND");
                jpgData = ReceiverUtils.receiveData(receiver, buffer);

                //Compress jpgData and write result to jpgBaos
                jpgBaos = ReceiverUtils.compressFrame(imgRect, jpgData);

                //Decode jpgData into Bitmap
                image = ReceiverUtils.getFrame(jpgBaos.toByteArray(), jpgSize);
                //image = ReceiverUtils.getFrame(jpgData, jpgSize);

                //Set buffer and jpgData to null since we aren't using them
                buffer = null;
                jpgData = null;

                //Draw Bitmap to canvas
                ReceiverUtils.draw(image, holder, imgRect);
                //break; (testing one run-through)
            }

            //Receive 'ready' flag from camcorder
            fromServer = ReceiverUtils.receiveText(receiver);
            if(isItOK == false){
                break;
            }
        }
        //break; (testing one run-through)
    }
    }

这是前一个代码段中调用的ReceiverUtils.compressFrame()。

/*----------------------------------------
 * compressFrame(Rect imgRect, byte[] input): Creates new instance of YuvImage used to compress ARGB 
 * byte array data to jpeg. Returns ByteArrayOutputStream with data.    
 */

    public static ByteArrayOutputStream compressFrame(Rect imgRect, byte[] input){
        boolean success = false;

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        YuvImage yuvImage = new YuvImage(input, ImageFormat.NV21, 
                  imgRect.width(), imgRect.height(), null);
        Log.e("HEY", "HEY");
        success = yuvImage.compressToJpeg(imgRect, 80, baos);
        Log.e("Compression Success:", String.valueOf(success));

        return baos;
    }

最后,这是我从LogCat获得的输出。 (注意一些明显仓促编写的调试日志。)

07-03 15:01:19.754: E/From server:(1634): ANDROID_JPG_READY_26907
07-03 15:01:19.754: E/JPG SIZE(1634): 26907
07-03 15:01:19.764: E/BUFFER SIZE(1634): 26907
07-03 15:01:19.764: E/To server:(1634): ANDROID_JPG_SEND
07-03 15:01:19.834: E/jpgIn(1634): Data received successfully.
07-03 15:01:19.834: E/HEY(1634): HEY
07-03 15:01:19.844: D/skia(1634): onFlyCompress

编辑:ReceiverUtils.getFrame()

/*---------------------------------------
 * getFrame(byte[] jpgData, int jpgSize): Decodes a byte array into a Bitmap and 
 * returns the Bitmap.
 */
    public static Bitmap getFrame(byte[] jpgData, int jpgSize){
        Bitmap res = null;

        res = BitmapFactory.decodeByteArray(jpgData, 0, jpgSize);
        Log.e("Decode success", String.valueOf(!(res == null)));            

        return res;
    }

编辑2:添加压缩前的代码

//Compress jpgData and write result to jpgBaos
//jpgBaos = ReceiverUtils.compressFrame(imgRect, jpgData);

//Decode jpgData into Bitmap
//image = ReceiverUtils.getFrame(jpgBaos.toByteArray(), jpgSize);
image = ReceiverUtils.getFrame(jpgData, jpgSize);

编辑3:保存到SD卡后的图像

Android在第一个代码段中的'jpgData'中保存的图像不是整个图像。由于是新用户,我无法发布。我添加了一个'writeToSD'方法来测试。我认为它无法解码的原因是因为大部分图像只是空白区域,而且只有一部分图像存在。

0 个答案:

没有答案