android bitmap drawable 图像特效处理收集与整理

赛克、冰冻、怀旧效果

六边形裁剪

class XfermodeActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_xfermode)

        btn1.setOnClickListener {
            imageview.setImageBitmap(BitmapFactory.decodeResource(resources ,R.mipmap.bg3 ))
        }

        btn2.setOnClickListener {
            var bitmap = (imageview.drawable as BitmapDrawable).bitmap
            imageview.setImageBitmap(getNewImage(bitmap))
        }
    }

    fun getNewImage(bitmap: Bitmap):Bitmap{
        var newBitmap = Bitmap.createBitmap(bitmap.width , bitmap.height , Bitmap.Config.ARGB_8888)
        var canvas = Canvas(newBitmap)
        canvas.translate(0f , 100f)
        var paint = Paint()
        var path = Path()
        path.moveTo(0f , bitmap.width*0.5f)
        path.lineTo(bitmap.width * 0.25f , 0f)
        path.lineTo(bitmap.width * 0.75f , 0f)
        path.lineTo(bitmap.width*1f  , bitmap.width * 0.5f)
        path.lineTo(bitmap.width*0.75f  , bitmap.width * 1f)
        path.lineTo(bitmap.width*0.25f  , bitmap.width *1f)
        path.close()

        canvas.drawPath(path, paint)
        paint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.SRC_IN))
        var rect = Rect(0,0,bitmap.width ,bitmap.height)
        canvas.drawBitmap(bitmap , null , rect , paint)
        return newBitmap
    }
}
原图 效果图
六边形原图.jpg
六边形效果图.jpg

抠图 从大图上抠掉小图所占的部分

class Xfermode2Activity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_xfermode2)

        var bitmap = (imageview_bg.drawable as BitmapDrawable).bitmap

        btn1.setOnClickListener {
            imageview_bg.setImageBitmap(bitmap)
        }

        btn2.setOnClickListener {
            var myWidth = bitmap.width
            var myHeight = bitmap.height
            var maskBitmap = BitmapFactory.decodeResource(resources ,R.mipmap.animal)
            var scalMaskBitmap = Bitmap.createScaledBitmap(maskBitmap , myWidth ,myHeight,true)
            var newbitmap = Bitmap.createBitmap(myWidth , myHeight ,Bitmap.Config.ARGB_8888)
            var canvas = Canvas(newbitmap)
            var paint = Paint()
            canvas.drawBitmap(scalMaskBitmap , (0).toFloat(),
                (0).toFloat() , paint)

            paint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.SRC_OUT))
            canvas.drawBitmap(bitmap , (0  ).toFloat() ,
                (0).toFloat() , paint)
            imageview_bg.setImageBitmap(newbitmap)

        }
    }
}
原图 效果图
抠图原图.jpg
抠图效果图.jpg

对比度

class ColormatrixActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_colormatrix)

        var width =  windowManager.defaultDisplay.width
//        var height = (imageview.drawable as BitmapDrawable).bitmap.height
        var option = BitmapFactory.Options()
        option.inJustDecodeBounds = true
        BitmapFactory.decodeResource(resources , R.mipmap.colormatrix, option)
        var scalWidth = option.outWidth/width

        var option2 = BitmapFactory.Options()
        option2.inSampleSize = scalWidth;
        var bitmap = BitmapFactory.decodeResource(resources , R.mipmap.colormatrix, option2)

        btn1.setOnClickListener {
            imageview.setImageBitmap(bitmap)
        }

        btn2.setOnClickListener {
            var myWidth = bitmap.width
            var myHeight = bitmap.height
            var myMatrix = floatArrayOf(5f,0f,0f,0f,-254f,
                                                0f,5f,0f,0f,-254f,
                                                0f,0f,5f,0f,-254f,
                                                0f,0f,0f,1f,0f)
            var newBitmap = Bitmap.createBitmap(myWidth ,myHeight ,Bitmap.Config.ARGB_8888)
            var canvas = Canvas(newBitmap)
            var paint = Paint()
            var colorMatrix = ColorMatrix()
            colorMatrix.set(myMatrix)
            paint.setColorFilter(ColorMatrixColorFilter(colorMatrix) as ColorFilter?)
            canvas.drawBitmap(bitmap,0f,0f,paint)
            imageview.setImageBitmap(newBitmap)
        }
    }
}
原图 效果图
对比度原图.jpg
对比度效果图.jpg

颜色过滤

class ColorFliterActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_color_fliter)

        btn0.setOnClickListener {
            imageview.setColorFilter(null)
        }

        btn1.setOnClickListener {
            imageview.setColorFilter(Color.GREEN , PorterDuff.Mode.MULTIPLY)
        }

        btn2.setOnClickListener {
            imageview.setColorFilter(Color.RED , PorterDuff.Mode.MULTIPLY)
        }

        btn3.setOnClickListener {
            imageview.setColorFilter(Color.BLUE , PorterDuff.Mode.MULTIPLY)
        }
    }
}
红色过滤 蓝色过滤
红色过滤.jpg
蓝色过滤.jpg

多色渐变

class SweepGradientActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(MyView(this))
    }

    inner class MyView(context: Context?) : View(context) {

        override fun onDraw(canvas: Canvas?) {
            super.onDraw(canvas)
            var myDisplay = windowManager.defaultDisplay
            var myWidth = myDisplay.width - 200
            var myHeight = myDisplay.height - 100
            var mySweepGradient = SweepGradient(myWidth/2.toFloat() , myHeight/2.toFloat() ,
                intArrayOf(Color.BLUE , Color.CYAN , Color.DKGRAY , Color.LTGRAY , Color.MAGENTA ,
                    Color.GREEN , Color.TRANSPARENT , Color.BLUE) , null)

            var paint = Paint()
            paint.setShader(mySweepGradient)
            canvas!!.translate(100f , -100f)
            canvas.drawCircle(myWidth/2.toFloat() , myHeight/2.toFloat() , myWidth/2.toFloat() , paint)
        }

    }
}
多色渐变.jpg

电波扩散

class RadialGradientActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(MyView(this))
    }

    inner class MyView: View {

         var myShader : Shader
         var myBitmap: Bitmap
         var myPaint: Paint
        var myRadialGradient: Shader? = null
        lateinit var myShapeDrawable: ShapeDrawable

        constructor(context: Context?):super(context){

            var myBitmap = (resources.getDrawable(R.mipmap.bg1) as BitmapDrawable).bitmap
            var myMetrics  = resources.displayMetrics
            this.myBitmap = Bitmap.createScaledBitmap(myBitmap ,myMetrics.widthPixels ,
                myMetrics.heightPixels , true)
            myShader  = BitmapShader(myBitmap , Shader.TileMode.REPEAT , Shader.TileMode.MIRROR)
            myPaint = Paint()
        }

        override fun onDraw(canvas: Canvas?) {
            super.onDraw(canvas)
            myShapeDrawable = ShapeDrawable(null)
            myShapeDrawable.paint.setShader(myShader)
            myShapeDrawable.setBounds(0,0,myBitmap.width ,myBitmap.height)
            myShapeDrawable.draw(canvas!!)
            if(myRadialGradient != null){
                myPaint.setShader(myRadialGradient)
                canvas.drawCircle(0f,0f,2000f,myPaint)
            }
        }

        override fun onTouchEvent(event: MotionEvent?): Boolean {
            myRadialGradient = RadialGradient(event!!.getX() , event.getY() , 48f ,
                intArrayOf(Color.WHITE , Color.TRANSPARENT) , null ,Shader.TileMode.REPEAT)
            postInvalidate()
            return true
        }

    }
}
原图 效果图
电波扩散原图.jpg
电波扩散效果图.jpg

内阴影

class ComposeShaderActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_compose_shader)

        var bitmap = BitmapFactory.decodeResource(resources,R.mipmap.bg3)
        btn1.setOnClickListener {
            imageview_bg.setImageBitmap(bitmap)
        }

        btn2.setOnClickListener {
            var  width = bitmap.width
            var  height = bitmap.height
            var paint = Paint()
            var bitmapShader = BitmapShader(bitmap , Shader.TileMode.REPEAT ,
                Shader.TileMode.REPEAT)
            var radialGradient = RadialGradient(width/2.toFloat() , height/2.toFloat() ,width/2.toFloat() ,
                Color.TRANSPARENT , Color.BLACK , Shader.TileMode.CLAMP)

            var compeseShader = ComposeShader(bitmapShader , radialGradient , PorterDuffXfermode(PorterDuff.Mode.SRC_OVER))
            paint.setShader(compeseShader)

            var bimapCopy = Bitmap.createBitmap(width,height ,Bitmap.Config.ARGB_8888)
            var canvas = Canvas(bimapCopy)
            canvas.drawRect(0f,0f,width.toFloat(),height.toFloat(),paint)
            imageview_bg.setImageBitmap(bimapCopy)

        }
    }
}
原图 效果图
内阴影原图.jpg
内阴影效果图.jpg

图片切割

class ShapeDrawableActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_shape_drawable)

        var drawable = getDrawable(R.mipmap.bg1)

        btn1.setOnClickListener {
            imageview.setImageDrawable(drawable)
        }

        btn2.setOnClickListener {
            var bitmap = BitmapFactory.decodeResource(resources ,R.mipmap.bg1)
            var path = Path()
            path.moveTo(200f,100f)
            path.lineTo(300f,300f)
            path.lineTo(100f , 300f)
            path.close()

            var bitmapDrawable = ShapeDrawable(PathShape(path , drawable!!.intrinsicWidth.toFloat() ,drawable!!.intrinsicHeight.toFloat()))
            var bitmapShader = BitmapShader(bitmap , Shader.TileMode.CLAMP ,Shader.TileMode.CLAMP)
            bitmapDrawable.paint.setShader(bitmapShader)
            imageview.setImageDrawable(bitmapDrawable)
        }
    }
}
原图 效果图
图片切割原图.jpg
图片切割效果图.jpg

超大图加载

类似地图效果 不是大图缩放
整个控件当做根布局

public class LargeImageView extends View implements GestureDetector.OnGestureListener {
    private static final String TAG = "LargeImageView";

    private BitmapRegionDecoder mDecoder;

    /**
     * 绘制的区域
     */
    private volatile Rect mRect = new Rect();

    private int mScaledTouchSlop;

    // 分别记录上次滑动的坐标
    private int mLastX = 0;
    private int mLastY = 0;
    /**
     * 图片的宽度和高度
     */
    private int mImageWidth, mImageHeight;
    private GestureDetector mGestureDetector;
    private BitmapFactory.Options options;

    public LargeImageView(Context context) {
        this(context, null);
    }

    public LargeImageView(Context context,  AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LargeImageView(Context context,  AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;


        mScaledTouchSlop = ViewConfiguration.get(getContext())
                .getScaledTouchSlop();
        Log.d(TAG, "sts:" + mScaledTouchSlop);
        //初始化手势控制器
        mGestureDetector = new GestureDetector(context, this);

        //获取图片的宽高
        InputStream is = null;
        try {
            is = context.getResources().getAssets().open("largeimage.png");
            //初始化BitmapRegionDecode,并用它来显示图片
            //如果在decodeStream之前使用is,会导致出错
            // 此时流的起始位置已经被移动过了,需要调用is.reset()来重置,然后再decodeStream(imgInputStream, null, options)
            mDecoder = BitmapRegionDecoder
                    .newInstance(is, false);

            BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
            // Grab the bounds for the scene dimensions
            tmpOptions.inJustDecodeBounds = true;

            is.reset();

            BitmapFactory.decodeStream(is, null, tmpOptions);
            mImageWidth = tmpOptions.outWidth;
            mImageHeight = tmpOptions.outHeight;

            Log.e(TAG, "width:" + mImageWidth + ",height:" + mImageHeight);


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //把触摸事件交给手势控制器处理
        return mGestureDetector.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        mLastX = (int) e.getRawX();
        mLastY = (int) e.getRawY();
        return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {

        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        int x = (int) e2.getRawX();
        int y = (int) e2.getRawY();
        move(x, y);

        return true;
    }

    /**
     * 移动的时候更新图片显示的区域
     *
     * @param x
     * @param y
     */
    private void move(int x, int y) {

        boolean isInvalidate = false;

        int deltaX = x - mLastX;
        int deltaY = y - mLastY;
        Log.d(TAG, "move, deltaX:" + deltaX + " deltaY:" + deltaY);
        //如果图片宽度大于屏幕宽度
        if (mImageWidth > getWidth()) {
            //移动rect区域
            mRect.offset(-deltaX, 0);
            //检查是否到达图片最右端
            if (mRect.right > mImageWidth) {
                mRect.right = mImageWidth;
                mRect.left = mImageWidth - getWidth();
            }

            //检查左端
            if (mRect.left < 0) {
                mRect.left = 0;
                mRect.right = getWidth();
            }
            isInvalidate = true;

        }
        //如果图片高度大于屏幕高度
        if (mImageHeight > getHeight()) {
            mRect.offset(0, -deltaY);

            //是否到达最底部
            if (mRect.bottom > mImageHeight) {
                mRect.bottom = mImageHeight;
                mRect.top = mImageHeight - getHeight();
            }

            if (mRect.top < 0) {
                mRect.top = 0;
                mRect.bottom = getHeight();
            }
            isInvalidate = true;

        }

        if (isInvalidate) {
            invalidate();
        }

        mLastX = x;
        mLastY = y;
    }

    @Override
    public void onLongPress(MotionEvent e) {
        mLastX = (int) e.getRawX();
        mLastY = (int) e.getRawY();
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        int x = (int) e2.getRawX();
        int y = (int) e2.getRawY();
        move(x, y);
        return true;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        //显示图片
        Bitmap bm = mDecoder.decodeRegion(mRect, options);
        canvas.drawBitmap(bm, 0, 0, null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        int imageWidth = mImageWidth;
        int imageHeight = mImageHeight;

        //默认显示图片的中心区域
        mRect.left = imageWidth / 2 - width / 2;
        mRect.top = imageHeight / 2 - height / 2;
        mRect.right = mRect.left + width;
        mRect.bottom = mRect.top + height;

    }

}

图片放在assets目录下


图片目录.png
超大图加载.gif
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容