• android 以不规则图片为边框切割另外图片


    转自:http://blog.sina.com.cn/s/blog_474928c90101dkvf.html

    最近工作上遇到了一个将一个图片按照相框进行裁剪的问题,花了一个下午研究了下,在此整理一下,以便后用。

     

              +            =     

       (相片)                                              (相框)                                             (结果图)
     
    一个按照边框裁剪的类,因为相框通体为蓝色,只是不同区域的透明度不同,所以,选用了根据透明度来筛选边界上的点的方法。
     
    另外,这个类也提供了判断一个点是否是在相框内部的方法:
    和当前像素点同一水平线上的各点,假如左右两侧均有相框蓝色边界上的点的话,并且当前点不在边框上则认为当前点在相框的内部
    反之,则认为当前点在相框的外部。
    package com.example.test_filter;
    
    import android.graphics.Bitmap;
    import android.graphics.Color;
    import android.graphics.Matrix;
    import android.graphics.Bitmap.Config;
    
    public class AlphaFilter implements Filter{
    
        public static final int INSIDE_MODE = 0;
        public static final int EDGE_MODE = 1;
        public static final int OUTSIDE_MODE = 2;
        
        public int findNonOpaque(int x, int y, int width, int height, int[] srcPixels) {
            if(width < height) {
                return findNonOpaqueByX(x, y, width, height, srcPixels);
            } else {
                return findNonOpaqueByY(x, y, width, height, srcPixels);
            }
        }
        
        /*
         * 横向检测左右两侧边界
         */
        public int findNonOpaqueByX(int x, int y, int width, int height, int[] srcPixels) {
            int mode = OUTSIDE_MODE;
            //当前点左右两侧均有边界点出现,则认为当前点在内部或者边框中
            if(findNonOpaqueByXLeft(x, y, width, height, srcPixels) && findNonOpaqueByXRight(x, y, width, height, srcPixels)) {
                mode = INSIDE_MODE;
            }
            int pos = y*width+x;
            if(isMatch(pos, srcPixels)) {
                mode = EDGE_MODE;
            }
            return mode;
        }
        
        /*
         * 检测与当前点y坐标相同的左侧各点是否有边界存在
         */
        public boolean findNonOpaqueByXLeft(int x, int y, int width, int height, int[] srcPixels) {
            for(int i=0; i < x; i++) {
                int pos = y*width + i;
                if(isMatch(pos, srcPixels)) {
                    return true;
                }
            }
            return false;
        }
        
        /*
         * 检测与当前点y坐标相同的右侧各点是否有边界存在
         */
        public boolean findNonOpaqueByXRight(int x, int y, int width, int height, int[] srcPixels) {
            for(int i= x+1; i < width; i++) {
                int pos = y*width + i;
                if(isMatch(pos, srcPixels)) {
                    return true;
                }
            }
            return false;
        }
        
        /*
         * 纵向检测上下两侧的边界
         */
        public int findNonOpaqueByY(int x, int y, int width, int height, int[] srcPixels) {
            int mode = OUTSIDE_MODE;
            //当前点上下两侧均有边界点出现,则认为当前点在内部或者边框中
            if(findNonOpaqueByYTop(x, y, width, height, srcPixels) && findNonOpaqueByYBottom(x, y, width, height, srcPixels)) {
                mode = INSIDE_MODE;
            }
            int pos = y*width+x;
            if(isMatch(pos, srcPixels)) {
                mode = EDGE_MODE;
            }
            return mode;
        }
        
        /*
         * 检测与当前点x坐标相同的上方各点是否有边界存在
         */
        public boolean findNonOpaqueByYTop(int x, int y, int width, int height, int[] srcPixels) {
            for(int i=0; i < y; i++) {
                int pos = i*width + x;
                if(isMatch(pos, srcPixels)) {
                    return true;
                }
            }
            return false;
        }
        
        /*
         * 检测与当前点x坐标相同的下方各点是否有边界存在
         */
        public boolean findNonOpaqueByYBottom(int x, int y, int width, int height, int[] srcPixels) {
            for(int i=y+1; i < height; i++) {
                int pos = i*width + x;
                if(isMatch(pos, srcPixels)) {
                    return true;
                }
            }
            return false;
        }
        
        public boolean isMatch(int pos, int[]srcPixels) {
            int color = srcPixels[pos];
            int alpha = Color.alpha(color);
            //检测是否是边界,针对背景图片选用透明度进行过滤
            if(alpha >= 94 && alpha < 255) {
                return true;
            }
            return false;
        }
        
        /**
         * 图片效果叠加
         * @param bmp 要裁剪的图片
         * @param filter 边框
         * @return
         */
        public Bitmap overlay(Bitmap bmp, Bitmap filter)
        {
            int width = bmp.getWidth();
            int height = bmp.getHeight();
            Bitmap overlay = filter;
            Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_4444);
            bitmap.setHasAlpha(true); 
            
            // 对边框图片进行缩放
            int w = overlay.getWidth();
            int h = overlay.getHeight();
            float scaleX = width * 1F / w;
            float scaleY = height * 1F / h;
            Matrix matrix = new Matrix();
            matrix.postScale(scaleX, scaleY);
            
            Bitmap overlayCopy = Bitmap.createBitmap(overlay, 0, 0, w, h, matrix, true);
            
            int[] srcPixels = new int[width * height];
            int[] layPixels = new int[width * height];
            bmp.getPixels(srcPixels, 0, width, 0, 0, width, height);
            overlayCopy.getPixels(layPixels, 0, width, 0, 0, width, height);
            
            int pos = 0;
            for (int i = 0; i < height; i++)
            {
                for (int k = 0; k < width; k++)
                {
                    pos = i * width + k;
                    
                    int mode = findNonOpaque(k, i, width, height, layPixels);
                    if(mode == INSIDE_MODE) {
                        srcPixels[pos] = srcPixels[pos];
                        continue;
                    } else if(mode == EDGE_MODE){
                        srcPixels[pos] = layPixels[pos];
                    } else{
                        srcPixels[pos] = 0;
                        continue;
                    }
                    
                }
            }
            bitmap.setPixels(srcPixels, 0, width, 0, 0, width, height);
            return bitmap;
        }
    }
    
    
    
    package com.example.test_filter;
    
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.app.Activity;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.widget.ImageView;
    
    public class MainActivity extends Activity {
    
        ImageView filter;
        AlphaFilter alphaFilter;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            filter = (ImageView) findViewById(R.id.filter);
            alphaFilter = new AlphaFilter();
        }
    
        @Override
        protected void onResume() {
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.album_photo_0);
            Bitmap frame = BitmapFactory.decodeResource(getResources(), R.drawable.first_album_frame);
            new BitmapFilter().execute(bitmap, frame);
            super.onResume();
        }
    
        class BitmapFilter extends AsyncTask<Bitmap, Bitmap, Bitmap> {
    
            @Override
            protected Bitmap doInBackground(Bitmap... params) {
                Bitmap bitmap = alphaFilter.overlay(params[0], params[1]);
                return bitmap;
            }
    
            @Override
            protected void onPostExecute(Bitmap result) {
                filter.setImageBitmap(result);
                super.onPostExecute(result);
            }
            
            
        }
    }
  • 相关阅读:
    vue项目进行时,script标签中,methods事件中函数使用的async/await
    css阴影——box-shadow
    vue报错——Module not found: Error: Can't resolve 'less-loader sass' in ...
    vue组件如何引入外部.js/.css/.scss文件
    获得汉字的拼音或者拼音简写
    model转XML
    sql server 添加表注释、字段注释
    (转)SQL Server 监控统计阻塞脚本信息
    系统首页右下角弹框
    DropDownListExtend控件
  • 原文地址:https://www.cnblogs.com/Anita9002/p/4203739.html
Copyright © 2020-2023  润新知