0

以下の3つの編集すべてを参照してください

更新:「read()」を「readFully()」に変更し、いくつかの機能を追加しました。'decodeByteArray()'はnullを返さなくなりました。カードに書き込まれるjpegは、実際には完全な画像です。画像はまだ私のビューに描画されていません。作業を続け、必要に応じて別の質問を投稿します。

DataInputStreamから画像を取り込むビデオストリーミングクライアントプログラムを作成しています。

サーバーがこれらの画像に対してcompressToJpeg()を呼び出すため、DataInputStreamからバイト配列を取得してデコードし、decodeByteArray()からSurfaceViewにビットマップを描画できると考えました。残念ながら、そのメソッドでは、decodeByteArray()がnullを返すだけです。

そこで、中間ステップを追加しました。ストリームからバイト配列を取得し、新しいYuvImageインスタンスを作成し、それを使用してcompressToJpeg()を呼び出すcompressFrame()メソッドを作成しました。ただし、実行すると、このメソッドは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」メソッドを追加しました。デコードできないのは、画像の大部分が空白で、画像の一部しか存在しないためだと思います。

4

0 に答える 0