Android实现图片的倒影效果

原理:

原图和倒影图分解成两个Bitmap, 倒影的Bitmap设计为原图的高度一半,宽度一致。然后创建一个可变空的Bitmap, 宽度跟原图保持一致,宽度为原图的1.5倍(宽度包括原图和倒影图的宽度之和),然后用Canvas关联这个可变空的Bitmap,在Canvas上将原图和倒影图依次绘制上去就行,为了打到倒影的效果,需要设计渐变等效果。

主要逻辑如下:

package com.jackie.revertbitmap;

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;
    }
}

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)    //滤色效果

};

效果图如下:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-07 15:55:12

Android实现图片的倒影效果的相关文章

Android 设置图片倒影效果

首先,贴出效果图: 1.布局文件main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_p

浅谈android中图片处理之图形变换特效Matrix(四)

今天,我们就来谈下android中图片的变形的特效,在上讲博客中我们谈到android中图片中的色彩特效来实现的.改变它的颜色主要通过ColorMatrix类来实现. 现在今天所讲的图片变形的特效主要就是通过Matrix类来实现,我们通过上篇博客知道,改变色彩特效,主要是通过ColorMatrxi矩阵的系数,以及每个像素点上所对应的颜色偏移量.而今天的图形变换与那个也是非常的类似.它是一个3*3矩阵,而颜色矩阵则是一个4*5的矩阵.在这个3*3矩阵中则表述出了每个像素点的XY坐标信息.然后通过修

Android 解决图片大量下载:软引用必须懂4点

Android 解决图片大量下载:软引用必须懂4点 可能对于Android开发者来说,软引用这个词有的会不是很熟悉,软引用在Java开发中用的比较多,但是,在Android开发中引用软引用,会给我们解决很多难题. AD: 1.对象的强.软.弱和虚引用 为了能更加灵活控制对象的生命周期,需要知道对象引用的4中级别,由高到低依次为 :强引用.软引用.弱引用和虚引用 备注: 这四种的区别: ⑴强引用(StrongReference) 强引用是使用最普遍的引用.如果一个对象具有强引用,那垃圾回收器绝不会

仿优酷Android客户端图片左右滑动(自动滑动)

最终效果: 页面布局main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent

Android圆形图片--自定义控件

Android圆形图片控件效果图如下: 代码如下: RoundImageView.java package com.dxd.roundimageview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas

android获取图片的旋转角度

public static int getExifOrientation(String filepath) { int degree = 0; ExifInterface exif = null; try { exif = new ExifInterface(filepath); } catch (IOException ex) { Log.d(TAG, "cannot read exif" + ex); } if (exif != null) { int orientation =

android 拉伸图片

Android拉伸图片用的是9.png格式的图片,这种图片可以指定图片的那一部分拉伸,那一部分显示内容,美工给的小图片也能有很好的显示效果. 原背景图片 可以看到原背景图片很小,即使在再长的文字,背景图片的圆角也不会拉伸 制作###.9.png 打开Android 的sdk>tools>draw9patch.bat,将图片拖进去开始制作###.9.png 点击四周即可添加黑点,拖拉黑点可成线.图片四周的黑线和黑点都有不同的意思. 上面黑线或者点表示纵向可拉伸的区域 一般一个点即可 左边黑线或者

android 背景图片滚动

昨天在给客户端做天气展示页面的时候,发现很多app的天气页面背景图片都会缓慢移动,形成了一种3d的感觉.例如下雨,静态图片缓慢移动,雨滴位置变换感觉就真的在下雨.云朵的移动也很酷.于是研究了一下午.写了一个自定义view控件. 我的自定义控件继承了view,重写ondraw方法.本人C#转android才3个月,以下代码如有错或者有可以改进的地方,请各位在评论中指出.望不吝赐教! ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

android 背景图片的设置

在java文件中对控件设置背景图片 layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.bgimage)) 在设置中,通过发送广播对整个布局中的背景进行更改. menu_bg1.setOnClickListener(new SendBroadcast()); private class SendBroadcast implements View.OnClickListener { @Override public