Android中修改图片指定像素颜色及解决操作Bitmap时崩溃的问题
解决Android中操作Bitmap崩溃的问题
嘿,我来帮你排查这个问题~从你给出的Logcat报错信息可以看到,核心问题是**dang这个Bitmap对象是null**,所以你调用copy()、setPixel()或者getHeight()这些方法时,都会触发NullPointerException导致崩溃。
为什么你的getDrawingCache会返回null?
你用getDrawingCache()获取Bitmap的方式有几个潜在问题:
getDrawingCache()需要在View完成绘制之后调用,如果在onCreate()或者onStart()里直接调用,此时ImageView还没完成测量和绘制,就会返回null。- 即使成功拿到DrawingCache,这个Bitmap通常是**不可变(immutable)**的,直接调用
setPixel()也会抛出异常,因为不可变Bitmap不允许修改像素。
正确的修改指定像素的方法
下面给你两种可靠的方案,都是先获取可编辑的Bitmap副本,再进行像素修改:
方案1:从ImageView的Drawable中获取并创建可编辑副本
如果你的ImageView是加载本地资源(比如R.drawable.xxx),可以用这种方式:
background = (ImageView) findViewById(R.id.dangeon); Drawable drawable = background.getDrawable(); // 先判断Drawable是否是BitmapDrawable类型 if (drawable instanceof BitmapDrawable) { Bitmap originalBitmap = ((BitmapDrawable) drawable).getBitmap(); // 创建可编辑的Bitmap副本,第二个参数设为true表示可修改 Bitmap editableBitmap = originalBitmap.copy(Bitmap.Config.ARGB_8888, true); // 现在可以安全地修改像素了 editableBitmap.setPixel(10, 10, Color.rgb(45, 127, 0)); // 将修改后的Bitmap设置回ImageView background.setImageBitmap(editableBitmap); }
方案2:用Canvas绘制生成可编辑Bitmap
如果你的ImageView加载的是网络图片,或者不确定Drawable类型,推荐用Canvas绘制的方式:
background = (ImageView) findViewById(R.id.dangeon); // 用post确保在View绘制完成后执行 background.post(new Runnable() { @Override public void run() { int width = background.getWidth(); int height = background.getHeight(); // 创建和ImageView尺寸一致的可编辑Bitmap Bitmap editableBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(editableBitmap); // 将ImageView的内容绘制到Canvas上 background.draw(canvas); // 修改指定像素 editableBitmap.setPixel(10, 10, Color.rgb(45, 127, 0)); // 更新ImageView显示 background.setImageBitmap(editableBitmap); } });
额外注意事项
- 不要在
onCreate()里直接获取View的宽高,此时View还没完成测量,宽高会是0,用post()或者onWindowFocusChanged()来确保View已绘制完成。 - 操作Bitmap时要注意内存占用,大尺寸Bitmap容易引发OOM,不用的Bitmap可以调用
recycle()释放内存(不过Android 8.0+有自动内存管理,还是尽量按需创建)。
内容的提问来源于stack exchange,提问作者Aviv
相关产品推荐
相关产品推荐

