閱讀634 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Android 修改Bitmap 圖片像素的信息 R G B 顏色值 詳解

要想修改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:andro
    android:background="#888888"
    android:layout_height="150dip" android:layout_width="120dip" >  
	<cn.m15.demo.RecordingView
		android: 
		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);
	}

	@Override
	protected 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);
	}

}


最後更新:2017-04-02 16:47:36

  上一篇:go android中在Button任意位置加圖片效果
  下一篇:go 《iPhone與iPad開發實戰—iOS經典應用剖析》連載六