圖片懷舊效果的算法:
我們用顏色矩陣(ColorMatrix)來完成我們的懷舊效果。如果有不知道ColorMatrix的原理的話可以參考:Android學習筆記之圖像顏色處理(ColorMatrix)
這就是那個顏色矩陣。我們可以利用上面的計算方法來改變我們的顏色矩陣的值從而達到我們想要的效果。
上面的計算方法可以轉換為:
M =
在Android中,顏色矩陣M是以一維數組m=[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t]的方式進行存儲的。
M = [0.393,0.768,0.189,0,0 , 0.349 , 0.686, 0.168, 0 , 0, 0.272, 0.534, 0.131, 0 , 0, 0, 0 , 0 , 0,0]
具體操作:
自定義view
ColorView.java
[java]
package com.color;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.ImageView;
public class ColorView extends ImageView {
private Paint myPaint = null;
private Bitmap bitmap = null;
private ColorMatrix myColorMatrix = null;
//設置顏色值
private float[] colorArray = {(float) 0.393,(float) 0.768,(float) 0.189,0,0,
(float) 0.349,(float) 0.686,(float) 0.168,0,0,
(float) 0.272,(float) 0.534,(float) 0.131,0,0,
0,0,0,1,0};
public ColorView(Context context, AttributeSet attrs)
{
super(context, attrs);
bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.ww);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//新建畫筆對象
myPaint = new Paint();
//描畫(原始圖片)
canvas.drawBitmap(bitmap,0, 0, myPaint);
//新建顏色矩陣對象
myColorMatrix = new ColorMatrix();
//設置顏色矩陣的值
myColorMatrix.set(colorArray);
//設置畫筆顏色過濾器
myPaint.setColorFilter(new ColorMatrixColorFilter(myColorMatrix));
//描畫(處理後的圖片)
canvas.drawBitmap(bitmap,0,0,myPaint);
invalidate();
}
}
package com.color;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.ImageView;
public class ColorView extends ImageView {
private Paint myPaint = null;
private Bitmap bitmap = null;
private ColorMatrix myColorMatrix = null;
//設置顏色值
private float[] colorArray = {(float) 0.393,(float) 0.768,(float) 0.189,0,0,
(float) 0.349,(float) 0.686,(float) 0.168,0,0,
(float) 0.272,(float) 0.534,(float) 0.131,0,0,
0,0,0,1,0};
public ColorView(Context context, AttributeSet attrs)
{
super(context, attrs);
bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.ww);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//新建畫筆對象
myPaint = new Paint();
//描畫(原始圖片)
canvas.drawBitmap(bitmap,0, 0, myPaint);
//新建顏色矩陣對象
myColorMatrix = new ColorMatrix();
//設置顏色矩陣的值
myColorMatrix.set(colorArray);
//設置畫筆顏色過濾器
myPaint.setColorFilter(new ColorMatrixColorFilter(myColorMatrix));
//描畫(處理後的圖片)
canvas.drawBitmap(bitmap,0,0,myPaint);
invalidate();
}
}
main.xml佈局文件
[html]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/colorView_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.color.ColorView
android:id="@+id/myColorView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/colorView_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.color.ColorView
android:id="@+id/myColorView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
懷舊效果 原圖
方法2:
將每個像素點的RGB值先分離出來,然後再按照上面的三個算式分別重新計算出RGB值然後做為當前點的RGB值
ColorView.java
[java]
package com.color;
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.util.AttributeSet;
import android.widget.ImageView;
public class ColorView extends ImageView {
private Paint myPaint = null;
private Bitmap bitmap = null;
private int width,height;
public ColorView(Context context, AttributeSet attrs)
{
super(context, attrs);
bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.ww);
width = bitmap.getWidth();
height = bitmap.getHeight();
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int pixColor = 0;
int pixR = 0;
int pixG = 0;
int pixB = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];
//獲取圖片的像素(一維數組)
/*
* pixels 接收位圖顏色值的數組
* offset 寫入到pixels[]中的第一個像素索引值
* stride pixels[]中的行間距個數值(必須大於等於位圖寬度)。可以為負數
* x 從位圖中讀取的第一個像素的x坐標值。
* y 從位圖中讀取的第一個像素的y坐標值
* width 從每一行中讀取的像素寬度
* height 讀取的行數
*/
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
//獲取一個高height寬width的圖片像素
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
pixColor = pixels[width * i + j];
//等價於(pixColor >> 16) & 0xFF 獲取一個像素的R
pixR = Color.red(pixColor);
//等價於(pixColor >> 8) & 0xFF 獲取一個像素的G
pixG = Color.green(pixColor);
//等價於(pixColor) & 0xFF 獲取一個像素的B
pixB = Color.blue(pixColor);
//根據算法由原圖的RGB生成新的RGB
newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
//由RGB生成一個像素
//函數:argb (int alpha, int red, int green, int blue)
int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);
pixels[width * i + j] = newColor;
}
}
//生成新的圖片
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
//描畫(處理後的圖片)
canvas.drawBitmap(bitmap,0,0,myPaint);
}
}
package com.color;
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.util.AttributeSet;
import android.widget.ImageView;
public class ColorView extends ImageView {
private Paint myPaint = null;
private Bitmap bitmap = null;
private int width,height;
public ColorView(Context context, AttributeSet attrs)
{
super(context, attrs);
bitmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.ww);
width = bitmap.getWidth();
height = bitmap.getHeight();
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int pixColor = 0;
int pixR = 0;
int pixG = 0;
int pixB = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];
//獲取圖片的像素(一維數組)
/*
* pixels 接收位圖顏色值的數組
* offset 寫入到pixels[]中的第一個像素索引值
* stride pixels[]中的行間距個數值(必須大於等於位圖寬度)。可以為負數
* x 從位圖中讀取的第一個像素的x坐標值。
* y 從位圖中讀取的第一個像素的y坐標值
* width 從每一行中讀取的像素寬度
* height 讀取的行數
*/
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
//獲取一個高height寬width的圖片像素
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
pixColor = pixels[width * i + j];
//等價於(pixColor >> 16) & 0xFF 獲取一個像素的R
pixR = Color.red(pixColor);
//等價於(pixColor >> 8) & 0xFF 獲取一個像素的G
pixG = Color.green(pixColor);
//等價於(pixColor) & 0xFF 獲取一個像素的B
pixB = Color.blue(pixColor);
//根據算法由原圖的RGB生成新的RGB
newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
//由RGB生成一個像素
//函數:argb (int alpha, int red, int green, int blue)
int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);
pixels[width * i + j] = newColor;
}
}
//生成新的圖片
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
//描畫(處理後的圖片)
canvas.drawBitmap(bitmap,0,0,myPaint);
}
}