有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Android:Bitmap-to-Byte数组和back:SkImageDecoder::Factory返回null

目标是将Bitmap转换为byte [],在Bundle数据中的活动之间传递它,然后在稍后阶段将其重新转换回Bitmap以在Imageview中显示

问题是,每当我尝试此操作时,我只会得到一个空位图和非描述性、无用的日志输出:

12-07 17:01:33.282: D/skia(2971): --- SkImageDecoder::Factory returned null

我研究了以下解决方案:

Solution supplies the bitmap to byte[] code used

Highlighted that copyPixelsToBuffer() is essential over .compress

(尤其是在这种情况下不需要的情况下)

我已经运行了下面的测试用例,它明确地将问题缩小到转换和恢复代码。根据我的调试,解码正确,字节数组大小正确且完整,位图配置被迫相同,decodeByteArray只是失败了:

package com.example.debug;

import java.nio.ByteBuffer;

import 安卓.os.Bundle;
import 安卓.app.Activity;
import 安卓.graphics.Bitmap;
import 安卓.graphics.Bitmap.Config;
import 安卓.graphics.BitmapFactory;
import 安卓.util.Log;
import 安卓.view.Menu;
import 安卓.widget.ImageView;
import 安卓.widget.RelativeLayout;

public class MainActivity extends Activity {
    RelativeLayout rl = null;
    RelativeLayout.LayoutParams rlp = null;

    ImageView ivBef = null;
    ImageView ivAft = null;

    Bitmap bmBef = null;
    Bitmap bmAft = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // TEST
        BitmapFactory.Options bmo = new BitmapFactory.Options();
        bmo.inPreferredConfig = Config.ARGB_8888;

        bmBef = BitmapFactory.decodeFile("/mnt/sdcard/Debug/001.png", bmo);
        byte[] b = bitmapToByteArray(bmBef);
        bmAft = BitmapFactory.decodeByteArray(b, 0, b.length, bmo);

        LinearLayout ll = new LinearLayout(this);

        ivBef = new ImageView(this);
        ivBef.setImageBitmap(bmBef);

        ivAft = new ImageView(this);
        ivAft.setImageBitmap(bmAft);

        ll.addView(ivBef);
        ll.addView(ivAft);

        setContentView(ll);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    public static byte[] bitmapToByteArray(Bitmap bm) {
        // Create the buffer with the correct size
        int iBytes = bm.getWidth() * bm.getHeight() * 4;
        ByteBuffer buffer = ByteBuffer.allocate(iBytes);

        // Log.e("DBG", buffer.remaining()+""); -- Returns a correct number based on dimensions
        // Copy to buffer and then into byte array
        bm.copyPixelsToBuffer(buffer);
        // Log.e("DBG", buffer.remaining()+""); -- Returns 0
        return buffer.array();
    }

}

beforeImageview正确显示图像,beforeImageView不显示任何内容(如空位图所示)


共 (3) 个答案

  1. # 1 楼答案

    下面的方法非常适合我,试试看

    public byte[] convertBitmapToByteArray(Context context, Bitmap bitmap) {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream(bitmap.getWidth() * bitmap.getHeight());
        bitmap.compress(CompressFormat.PNG, 100, buffer);
        return buffer.toByteArray();
    }
    
  2. # 2 楼答案

    试试这个:

      bmBef = BitmapFactory.decodeFile("/mnt/sdcard/Debug/001.png", bmo);
      ByteArrayOutputStream baos= new ByteArrayOutputStream();
      bmBef .compress(Bitmap.CompressFormat.PNG, 100, baos);
      byte[] byteArray = baos.toByteArray();
    
  3. # 3 楼答案

    您正在将位图传递到Intent,并在下一个活动中从bundle获取位图,但问题是,如果您的位图/图像大小较大,则在下一个活动中不会加载图像

    使用以下两种解决方案来解决此问题

    1)首先将图像转换为字节数组,然后传递到Intent,在下一个活动中,从Bundle中获取字节数组,并将其转换为图像(位图)并设置为ImageView

    将位图转换为字节数组:-

    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] byteArray = stream.toByteArray();
    

    将字节数组传递到intent:-

    Intent intent = new Intent(this, NextActivity.class);
    intent.putExtra("picture", byteArray);
    startActivity(intent);
    

    从包中获取字节数组并转换为位图图像:-

    Bundle extras = getIntent().getExtras();
    byte[] byteArray = extras.getByteArray("picture");
    
    Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
    ImageView image = (ImageView) findViewById(R.id.imageView1);
    
    image.setImageBitmap(bmp);
    

    2)首先将图像保存到SD卡中,然后在下一个活动中将此图像设置到ImageView中