8

Serializableを実装するクラスTouchPointがあり、ビットマップが含まれているため、そのクラスのwriteObjectとreadObjectを記述しました。

private void writeObject(ObjectOutputStream oos) throws IOException {
    long t1 = System.currentTimeMillis();
    oos.defaultWriteObject();
    if(_bmp!=null){
        int bytes = _bmp.getWidth()*_bmp.getHeight()*4;

        ByteBuffer buffer = ByteBuffer.allocate(bytes); 
        _bmp.copyPixelsToBuffer(buffer);

        byte[] array = buffer.array();      

        oos.writeObject(array);

    }
    Log.v("PaintFX","Elapsed Time: "+(System.currentTimeMillis()-t1));
}

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
    ois.defaultReadObject();
    byte[] data = (byte[]) ois.readObject();
    if(data != null && data.length > 0){
        _bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
    }
}

問題は私が得ることです

SkImageDecoder::Factoryがnullを返しました

では、どうすれば修正できますか。考えられる解決策は、writeObject()を次のように変更することです。

ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
_bmp.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
oos.writeObject(byteStream.toByteArray);

しかし、この方法はほぼ10倍以上遅くなります。

  • copyPixelsToBuffer〜14ms画像の書き込み
  • _bmp.compress〜160ms

更新 実際の問題はその後の問題であることを確認してください

buffer.array();

すべてのbyte[]配列要素は次のとおりです:0

4

2 に答える 2

7

最後に、それを機能させると同時に高速化する方法を見つけました。この方法を使用すると、次の 2 つの問題が発生しました。

  1. Bitmap.Config パラメータも渡す必要があります。それがないと、バイト配列をデコードできません
  2. _bmp.compress と _bmp.copyPixelsToBuffer は異なる配列を与えるため、decodeByteArray を使用できませんでした。

私はこの方法でそれらを解決しました

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();

    if(_bmp!=null){
        int bytes = _bmp.getWidth()*_bmp.getHeight()*4;

        ByteBuffer buffer = ByteBuffer.allocate(bytes);
        _bmp.copyPixelsToBuffer(buffer);

        byte[] array = new byte[bytes]; // looks like this is extraneous memory allocation

        if (buffer.hasArray()) {
            try{
                array = buffer.array();
            } catch (BufferUnderflowException e) {
                e.printStackTrace();
            }
        }

        String configName = _bmp.getConfig().name();

        oos.writeObject(array);
        oos.writeInt(_bmp.getWidth());
        oos.writeInt(_bmp.getHeight());
        oos.writeObject(configName);
    } else {
        oos.writeObject(null);
    }
}

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
    ois.defaultReadObject();

    byte[] data = (byte[]) ois.readObject();
    if (data != null) {
        int w = ois.readInt();
        int h = ois.readInt();
        String configName = (String) ois.readObject();

        Bitmap.Config configBmp = Bitmap.Config.valueOf(configName);
        Bitmap bitmap_tmp = Bitmap.createBitmap(w, h, configBmp);
        ByteBuffer buffer = ByteBuffer.wrap(data);

        bitmap_tmp.copyPixelsFromBuffer(buffer);

        _bmp = bitmap_tmp.copy(configBmp,true);

        bitmap_tmp.recycle();
    } else {
        _bmp = null;
    }
}

これは私にとって十分に高速です.bmp.compressの方法よりも約15倍高速です。お役に立てれば :)

于 2012-06-03T14:38:00.697 に答える
1

ビットマップからバイト[]:

Bitmap bmp; // your bitmap
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();

パフォーマンスを向上させるには、Bufferedstreams を使用してください。

于 2012-05-31T18:10:48.347 に答える