Android 修改Bitmap 图片像素的信息 R G B 颜色值详解

要想修改Bitmap图片的 R G B信息 首先 得先拿到这张图片每个点的Color值 然后根据这个Color值 就可以算出对应的R G B 值 我们都知道在计算机语言中在内存中加载一张图片实际上是把图片的每个点的RGB信息写入内存 如果动态的修改了这些颜色信息 那绘制出来的图片就会改变。

修改图片的颜色值其实在很多地方都有用处,我记得以前我做J2ME游戏开发的时候 因为手机本身内存比较低 不能同时在内存中加载过多的图片 比如 在打怪的时候 玩家肯定不希望每次看到的怪物都一样 在不加大内存的情况下可以选择修改图片的R G B信息 就会给玩家耳目一新的感觉 这就是游戏调色板的原理。

接下来我介绍一下代码。下面这两张图片中的话筒图片中间的颜色是白色 在这里我动态的修改图片中间的颜色值 让它动起来。

Android 修改Bitmap 图片像素的信息 R G B 颜色值详解Android 修改Bitmap 图片像素的信息 R G B 颜色值详解

//启动activity

  1. packagecn.m15.demo;
  2. importAndroid.app.Activity;
  3. importAndroid.os.Bundle;
  4. importAndroid.view.Window;
  5. publicclassdemoActivityextendsActivity{
  6. @Override
  7. publicvoidonCreate(BundlesavedInstanceState){
  8. super.onCreate(savedInstanceState);
  9. requestWindowFeature(Window.FEATURE_NO_TITLE);
  10. setContentView(R.layout.main);
  11. }
  12. }

//布局文件 自定义了一个View 绘制 图片

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <RelativeLayoutxmlns:Android="http://schemas.android.com/apk/res/android"
  3. Android:background="#888888"
  4. Android:layout_height="150dip"android:layout_width="120dip">
  5. <cn.m15.demo.RecordingView
  6. Android:id="@+id/uvMeter"
  7. Android:layout_height="wrap_content"
  8. Android:layout_width="wrap_content"
  9. Android:gravity="center"
  10. />
  11. </RelativeLayout>

//自定义View

  1. packagecn.m15.demo;
  2. importjava.util.Random;
  3. importAndroid.content.Context;
  4. importAndroid.graphics.Bitmap;
  5. importAndroid.graphics.BitmapFactory;
  6. importAndroid.graphics.Canvas;
  7. importAndroid.graphics.Color;
  8. importAndroid.graphics.Paint;
  9. importAndroid.graphics.drawable.BitmapDrawable;
  10. importAndroid.util.AttributeSet;
  11. importAndroid.view.View;
  12. publicclassRecordingViewextendsView{
  13. PaintmPaint;
  14. BitmapmBitmap;
  15. intmBitmapWidth=0;
  16. intmBitmapHeight=0;
  17. intmArrayColor[]=null;
  18. intmArrayColorLengh=0;
  19. longstartTime=0;
  20. intmBackVolume=0;
  21. publicRecordingView(Contextcontext){
  22. super(context);
  23. init(context);
  24. }
  25. publicRecordingView(Contextcontext,AttributeSetattrs){
  26. super(context,attrs);
  27. init(context);
  28. }
  29. voidinit(Contextcontext){
  30. mPaint=newPaint(Paint.ANTI_ALIAS_FLAG);
  31. //在这里创建了一张bitmap
  32. mBitmap=BitmapFactory.decodeResource(context.getResources(),
  33. R.drawable.ic_vd_mic_on);
  34. //将这张bitmap设置为背景图片
  35. setBackgroundDrawable(newBitmapDrawable(mBitmap));
  36. mBitmapWidth=mBitmap.getWidth();
  37. mBitmapHeight=mBitmap.getHeight();
  38. mArrayColorLengh=mBitmapWidth*mBitmapHeight;
  39. mArrayColor=newint[mArrayColorLengh];
  40. intcount=0;
  41. for(inti=0;i<mBitmapHeight;i++){
  42. for(intj=0;j<mBitmapWidth;j++){
  43. //获得Bitmap图片中每一个点的color颜色值
  44. intcolor=mBitmap.getPixel(j,i);
  45. //将颜色值存在一个数组中方便后面修改
  46. mArrayColor[count]=color;
  47. //如果你想做的更细致的话可以把颜色值的RGB拿到做响应的处理笔者在这里就不做更多解释
  48. intr=Color.red(color);
  49. intg=Color.green(color);
  50. intb=Color.blue(color);
  51. count++;
  52. }
  53. }
  54. startTime=System.currentTimeMillis();
  55. }
  56. /**
  57. *返回一个随机数
  58. *
  59. *@parambotton
  60. *@paramtop
  61. *@return
  62. */
  63. intUtilRandom(intbotton,inttop){
  64. return((Math.abs(newRandom().nextInt())%(top+1-botton))+botton);
  65. }
  66. @Override
  67. protectedvoidonDraw(Canvascanvas){
  68. super.onDraw(canvas);
  69. //每隔100毫秒设置一下填充的颜色区域
  70. if(System.currentTimeMillis()-startTime>=100){
  71. startTime=System.currentTimeMillis();
  72. setVolume(UtilRandom(0,100));
  73. }
  74. //用于刷新屏幕
  75. invalidate();
  76. }
  77. publicvoidsetVolume(intvolume){
  78. intstartY=0;
  79. intendY=0;
  80. booleanisAdd=false;
  81. //判断当前应该填充新区域还是还原旧的区域
  82. if(mBackVolume>volume){
  83. isAdd=false;
  84. startY=getValue(mBackVolume);
  85. endY=getValue(volume);
  86. }else{
  87. isAdd=true;
  88. startY=getValue(volume);
  89. endY=getValue(mBackVolume);
  90. }
  91. //没必要每次都循环图片中的所有点,因为这样会比较耗时。
  92. intcount=startY*mBitmapWidth;
  93. //从图片须要填充或者还原颜色的起始点开始到终点
  94. for(inti=startY;i<endY;i++){
  95. for(intj=0;j<mBitmapWidth;j++){
  96. if(isAdd){
  97. //将需要填充的颜色值如果不是
  98. //在这说明一下如果color是全透明或者全黑返回值为0
  99. //getPixel()不带透明通道getPixel32()才带透明部分所以全透明是0x00000000
  100. //而不透明黑色是0xFF000000如果不计算透明部分就都是0了
  101. intcolor=mBitmap.getPixel(j,i);
  102. if(color!=0){
  103. mBitmap.setPixel(j,i,Color.BLACK);
  104. }
  105. }else{
  106. //如果是还原颜色把现在点的颜色赋值为之前保存颜色的数组
  107. mBitmap.setPixel(j,i,mArrayColor[count]);
  108. }
  109. count++;
  110. }
  111. }
  112. mBackVolume=volume;
  113. }
  114. //通过百分比根据图片宽高算出实际填充高度
  115. publicintgetValue(intvolume){
  116. returnmBitmapHeight-(mBitmapHeight*volume/100);
  117. }
  118. }