要想修改Bitmap圖片的 R G B資訊 首先 得先拿到這張圖片每個點的Color值 然後根據這個Color值 就可以算出對應的R G B 值 我們都知道在電腦語言中在記憶體中載入一張圖片實際上是把圖片的每個點的RGB資訊寫入記憶體 如果動態修改了這些顏色資訊 那繪製出來的圖片就會改變。
修改圖片的顏色值其實在很多地方都有用處,我記得以前我做J2ME遊戲開發的時候 因為手機本身記憶體比較低 不能同時在記憶體中載入過多的圖片 比如 在打怪的時候 玩家肯定不希望每次看到的怪物都一樣 在不加大記憶體的情況下可以選擇修改圖片的R G B資訊 就會給玩家耳目一新的感覺 這就是遊戲調色盤的原理。
接下來我介紹一下代碼。下面這兩張圖片中的話筒圖片中間的顏色是白色 在這裡我動態修改圖片中間的顏色值 讓它動起來。
//啟動activity
package cn.m15.demo;import android.app.Activity;import android.os.Bundle;import android.view.Window;public class demoActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.main); }}
//布局檔案 自訂了一個View 繪製 圖片
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="#888888" android:layout_height="150dip" android:layout_width="120dip" > <cn.m15.demo.RecordingViewandroid:id="@+id/uvMeter" android:layout_height="wrap_content" android:layout_width="wrap_content"android:gravity="center"/></RelativeLayout>
//自訂View
package cn.m15.demo;import java.util.Random;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;public class RecordingView extends View{Paint mPaint;Bitmap mBitmap;int mBitmapWidth = 0;int mBitmapHeight = 0;int mArrayColor[] = null;int mArrayColorLengh = 0;long startTime = 0;int mBackVolume = 0;public RecordingView(Context context) { super(context); init(context);}public RecordingView(Context context, AttributeSet attrs) { super(context, attrs); init(context);}void init(Context context) { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //在這裡建立了一張bitmap mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_vd_mic_on); //將這張bitmap設定為背景圖片 setBackgroundDrawable(new BitmapDrawable(mBitmap)); mBitmapWidth = mBitmap.getWidth(); mBitmapHeight = mBitmap.getHeight(); 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 = mBitmap.getPixel(j, i); //將顏色值存在一個數組中 方便後面修改 mArrayColor[count] = color; //如果你想做的更細緻的話 可以把顏色值的R G B 拿到做響應的處理 筆者在這裡就不做更多解釋 int r = Color.red(color); int g = Color.green(color); int b = Color.blue(color); count++;} } startTime = System.currentTimeMillis();}/** * 返回一個隨機數 * * @param botton * @param top * @return */int UtilRandom(int botton, int top) { return ((Math.abs(new Random().nextInt()) % (top + 1 - botton)) + botton);}@Overrideprotected void onDraw(Canvas canvas) { super.onDraw(canvas); //每隔100毫秒設定一下填充的顏色地區 if (System.currentTimeMillis() - startTime >= 100) {startTime = System.currentTimeMillis();setVolume(UtilRandom(0, 100)); } //用於重新整理螢幕 invalidate();}public void setVolume(int volume) { 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);}}