bitmap setPixels报java.lang.IllegalStateException异常解决方法


int w = 352;

int h = 288;
int[] pixels = new int[w * h * 10];
ImageView iv = (ImageView) findViewById(R.id.fImageView);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.icon2);// 创建对象
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(),bitmap.getHeight());// 放入
bitmap.setPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(),bitmap.getHeight());// 取出
iv.setImageBitmap(bitmap);// 显示

在bitmap.setPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(),bitmap.getHeight());出现了一下以下异常:
AndrodRuntime Caused by:java.lang.IllegalStateException
AndrodRuntime at android.graphics.Bitmap.setPixels(Bitmap.java:853)
AndrodRuntime at com.phd.canwasDemo.CanvasDemoF.onCreate(CanvasDemoF.java:37)
AndrodRuntime at android.app.Instrumentation.allActivityOnCreate(Instrumentation.java:1123)
AndrodRuntime at android.app.ActivityThread.performLaunchActivity(ActivityThread.java.2233)
AndrodRuntime ...11 more

但我运行
ImageView iv = (ImageView) findViewById(R.id.gImageView);
Bitmap b = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);// 创建bitmap对象
int[] pixels = new int[b.getWidth() * b.getHeight()];// 创建像素数组
b.setPixel(0, 0, 0xFF00FF00);
b.setPixel(0, 1, 0x8000FF00);
b.setPixel(1, 0, 0x0000FF00);
b.getPixels(pixels, 0, b.getWidth(), 0, 0, b.getWidth(), b.getHeight());
b.setPixels(pixels, 0, b.getWidth(), 0, 0, b.getWidth(), b.getHeight());
iv.setImageBitmap(b);
可正常运行并显示
请各位帮我分析下,该如何解决!

------解决方案--------------------
这个问题我测试过了,如果再建立一个
Bitmap bitmap2=Bitmap.createBitmap(w, h, Config.ARGB_8888);
然后使用
bitmap2.setPixels(pixels, 0, bitmap2.getWidth(), 0, 0, bitmap2.getWidth(),
bitmap2.getHeight());// 取出

显示
iv.setImageBitmap(bitmap2);// 显示
就可以了,我分析会不会是内存处理上的问题。 
------解决方案--------------------
我查了下,第一个错误应该是the bitmap is not mutable 
------解决方案--------------------
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.icon2);//返回的估计是一个immutalbe的bitmap;所以不能用setpixels

而Bitmap b = Bitmap.createBitmap(2, 2, Bitmap.Config.ARGB_8888);//返回的是一个mutable的bitmap,可以用setpixels


------解决方案--------------------
从Bitmap.createBitmap可以看到有的返回immutable bitmap,有的返回 mutable bitmap

1。static Bitmap createBitmap(Bitmap src)
Returns an immutable bitmap from the source bitmap.

2.static Bitmap createBitmap(int[] colors, int width, int height, Bitmap.Config config)
Returns a immutable bitmap with the specified width and height,

3.static Bitmap createBitmap(int[] colors, int offset, int stride, int width, int height, Bitmap.Config config)
Returns a immutable bitmap with the specified width and height,  

4.static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter)
Returns an immutable bitmap from subset of the source bitmap,  

5.static Bitmap createBitmap(int width, int height, Bitmap.Config config)
Returns a mutable bitmap with the specified width and height.

6.static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height)

Returns an immutable bitmap from the specified subset of the source bitmap.


引用实例:

//实现类似录音时,动态变化的录音图片

package com.app.bigbang;


import java.util.Random;


import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.View;

//自定义view后在布局文件里面调用
public class RecordView extends View {
    
Paint mPaint;
Bitmap mBitmap;
int mBitmapWidth = 0;
int mBitmapHeight = 0;
int mArrayColorLengh = 0; 
int mArrayColor[] = null;  
long startTime = 0; 
int mBackVolume = 0; 
Bitmap bmp;

public RecordView(Context context) {
super(context);
init(context);
// TODO Auto-generated constructor stub
}
public RecordView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
// TODO Auto-generated constructor stub
}
public RecordView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
// TODO Auto-generated constructor stub
}
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
private void init(Context context){
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.jiangfeilv);//获取资源文件里面的图片,返回immutable的Bitmap
mBitmapWidth = bmp.getWidth();
mBitmapHeight = bmp.getHeight();
mBitmap = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight, Bitmap.Config.ARGB_8888);//创建资源文件图片大小的图片,返回mutable
mArrayColorLengh = mBitmapWidth * mBitmapHeight;
mArrayColor = new int[mArrayColorLengh];
int count = 0;
for (int i = 0; i < mBitmapHeight; i++) {  
       for (int j = 0; j < mBitmapWidth; j++) {
        //获得Bitmap 图片中每一个点的color颜色值  
           int color = bmp.getPixel(j, i);  
           mBitmap.setPixel(j, i, color);  //给mutable的Bitmap设置像素点,使其显示成资源文件里面的图片
           //将颜色值存在一个数组中 方便后面修改  
           mArrayColor[count] = color;  
           //如果你想做的更细致的话 可以把颜色值的R G B 拿到做响应的处理 笔者在这里就不做更多解释 
           int r = Color.red(color);
           int g = Color.green(color);
           int b = Color.blue(color);
           count++;
       }
}
setBackground(new BitmapDrawable(mBitmap));
startTime = System.currentTimeMillis();
}

//返回随机数
int UtilRandom(int bottom,int top){
return ((Math.abs(new Random().nextInt())%(top+1-bottom))+bottom);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
if(System.currentTimeMillis() - startTime >= 100){
startTime = System.currentTimeMillis();
setVolum(UtilRandom(0,100));
}
//用于刷新屏幕  
       invalidate();
}
private void setVolum(int volume) {
// TODO Auto-generated method stub
int  startY = 0;
int endY = 0;
boolean isAdd = false;
//判断当前应该填充新区域 还是还原旧的区域 
if(mBackVolume > volume ){
isAdd = false;
startY = getValue(mBackVolume);
endY = getValue(volume);
}else{
isAdd = true;
startY = getValue(volume);
endY = getValue(mBackVolume);
}
//没必要每次都循环图片中的所有点,因为这样会比较耗时。  
        int count = startY * mBitmapWidth;  
        //从图片须要填充或者还原 颜色的起始点 开始 到 终点   
        for (int i = startY; i < endY; i++) {  
        for (int j = 0; j < mBitmapWidth; j++) {  
            if (isAdd) {  
            //将需要填充的颜色值如果不是  
            //在这说明一下 如果color 是全透明 或者全黑 返回值为 0  
            //getPixel()不带透明通道 getPixel32()才带透明部分 所以全透明是0x00000000   
            //而不透明黑色是0xFF000000 如果不计算透明部分就都是0了  
            int color = mBitmap.getPixel(j, i);  
            if (color != 0) {  
                mBitmap.setPixel(j, i, Color.BLACK);  
            }  
            } else {  
            //如果是还原颜色 把现在点的颜色 赋值为之前保存颜色的数组  
            mBitmap.setPixel(j, i, mArrayColor[count]);  
            }  
            count++;  
        }  
        }  
        mBackVolume = volume; 

}

//通过百分比 根据图片宽高算出实际填充 高度  
    public int getValue(int volume) {  
        return mBitmapHeight - (mBitmapHeight * volume / 100);  
    }  


}



阅读更多
个人分类: android
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭