Android實現圖片的倒影效果

jopen 9年前發布 | 950 次閱讀 Java Android

原理:

原圖和倒影圖分解成兩個Bitmap, 倒影的Bitmap設計為原圖的高度一半,寬度一致。然后創建一個可變空的Bitmap, 寬度跟原圖保持一致,寬度為原圖的1.5倍(寬度包括原圖和倒影圖的寬度之和),然后用Canvas關聯這個可變空的Bitmap,在Canvas上將原 圖和倒影圖依次繪制上去就行,為了更接近倒影的效果,需要設計漸變等效果。

主要邏輯如下:


import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.ImageView;

public class MainActivity extends Activity {
private ImageView mRevertImageView;
private Bitmap mSourceBitmap; //原圖
private Bitmap mRevertBitmap; //倒立圖

@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.activity_main);  

    mRevertImageView = (ImageView)findViewById(R.id.im_revert);  
    mSourceBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.source);  
    mRevertImageView.setBackground(new BitmapDrawable(getResources(), revertBitmap()));  
}  

private Bitmap revertBitmap() {  
    //1.倒立圖  
    Matrix matrix = new Matrix();  
    matrix.preScale(1, -1);   //以X軸向下翻轉  
    int width = mSourceBitmap.getWidth();  
    int height = mSourceBitmap.getHeight();  

    //生成倒立圖,寬度和原圖一致,高度為原圖的一半  
    mRevertBitmap = Bitmap.createBitmap(mSourceBitmap, 0, height / 2, width, height / 2, matrix, false);  

    //2.要生成原圖加上倒立圖,先生成一個可變空的Bitmap, 高度為原圖高度的1.5倍(包括原圖和倒立圖的高度)  
    int gap = 10; //間隙空白  
    Bitmap bitmap = Bitmap.createBitmap(width, height + height / 2, Bitmap.Config.ARGB_8888);  
    Paint paint = new Paint();  
    Canvas canvas = new Canvas(bitmap);  
    canvas.drawBitmap(mSourceBitmap, 0, 0, paint);  //繪制原圖  
    canvas.drawBitmap(mRevertBitmap, 0, height + gap, paint);  //繪制倒立圖  

    //3.畫筆使用LinearGradient 線性漸變渲染  
    LinearGradient lg = new LinearGradient(0, height + gap, width, bitmap.getHeight(), 0xabff0000, 0x00ffff00, Shader.TileMode.MIRROR);  
    paint.setShader(lg);  

    //4.指定畫筆的Xfermode 即繪制的模式(不同的模式,繪制的區域不同)  
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP));  

    //5.在倒立圖區,繪制矩形渲染圖層  
    canvas.drawRect(0, height + gap, width, bitmap.getHeight(), paint);  
    paint.setXfermode(null);  
    return bitmap;  
}  

//縮放圖片  
private Bitmap resizeImage(Bitmap bitmap, int width, int height) {  
    int originWidth = bitmap.getWidth();  
    int originHeight = bitmap.getHeight();  

    float scaleWidth = width / originWidth;  
    float scaleHeight = height / originHeight;  

    Matrix matrix = new Matrix();  
    matrix.postScale(scaleWidth, scaleHeight);  
    Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, originWidth, originHeight, matrix, true);  
    return resizeBitmap;  
}  

} </pre>
PorterDuffXfermode 定義的模式如下:
private static final Xfermode[] sModes = {
 new PorterDuffXfermode(PorterDuff.Mode.CLEAR),     //所繪制不會提交到畫布上
 new PorterDuffXfermode(PorterDuff.Mode.SRC),       //顯示上層繪制圖片
 new PorterDuffXfermode(PorterDuff.Mode.DST),      //顯示下層繪制圖片
 new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER), //正常繪制顯示,上下層繪制疊蓋
 new PorterDuffXfermode(PorterDuff.Mode.DST_OVER), //上下層都顯示。下層居上顯示
 new PorterDuffXfermode(PorterDuff.Mode.SRC_IN),   //取兩層繪制交集。顯示上層
 new PorterDuffXfermode(PorterDuff.Mode.DST_IN),   //取兩層繪制交集。顯示下層
 new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT),  //取上層繪制非交集部分
 new PorterDuffXfermode(PorterDuff.Mode.DST_OUT),  //取下層繪制非交集部分
 new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP), //取下層非交集部分與上層交集部分
 new PorterDuffXfermode(PorterDuff.Mode.DST_ATOP), //取上層非交集部分與下層交集部分
 new PorterDuffXfermode(PorterDuff.Mode.XOR),      //濾色效果
 new PorterDuffXfermode(PorterDuff.Mode.DARKEN),   //濾色效果
 new PorterDuffXfermode(PorterDuff.Mode.LIGHTEN),  //濾色效果
 new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY), //濾色效果
 new PorterDuffXfermode(PorterDuff.Mode.SCREEN)    //濾色效果
};

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!