Android圖像處理:懷舊效果

圖片懷舊效果的算法:

 

 

 

 我們用顏色矩陣(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);

}

}

 

 

 

 

 

 

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *