• 自定义之一个图片根据另一个图片形状进行裁剪


    大佬绕道,本人小白

    先上一个原型图(gif 懒得弄)

    这里写图片描述

    怎么样 我这个原型图是不是很厉害 哈哈哈~~~

    • 需求:
      3. 源图( 图 1 )
      4. 需要被裁剪成某个形状 ( 图 2 )
      5. 最终效果( 图 3 )

    • 首先先引入资源文件 在values下创建名称为attrs的文件

    这里写图片描述

    • 配置attrs中的资源属性(因为我都加入注释了 所以看注释就应该懂了 我就不再这里多说了)
      那个format 就是类型 里边有好多类型 具体的可以百度
    <declare-styleable name="TailorDimView" >
            <!--被覆盖-->
            <attr name="image_dst" format="reference"></attr>
            <!--覆盖-->
            <attr name="image_src" format="reference"></attr>
            <!--透明度-->
            <attr name="trans" format="integer"></attr>
        </declare-styleable>
    
    • 下一步在xml中引用 dst和src 是两张图片 具体会在下面讲到
    <com.haiyunx.android.kxw.view.TailorDimView
            android:id="@+id/tdv_tailor_dim"
            android:layout_width="match_parent"
            android:scaleType="fitXY"
            tailor:image_dst="@mipmap/find_head_bg"
            tailor:image_src="@mipmap/test"
            tailor:trans="50"
            android:layout_height="165dp" />
    
    • 先把公共的方法写出来 方便写出来
    public TailorDimView setBitmap_Dst(Bitmap bitmap_dst) {
            this.B_Dst = bitmap_dst;
            return this;
        }
    
        public TailorDimView setBitmap_Src(Bitmap bitmap_src) {
            this.B_Src = bitmap_src;
            return this;
        }
        public TailorDimView setTransparency(int l){
            this.transparency = l;
            return this;
        }
        public void refresh(){
            initBitmap() ;
        }
    

    调用 第一个是不设置透明度 默认100,第二个设置透明度 70 ---------(100不透明 0全透明)

     tdvTailorDim.setBitmap_Src(src).setBitmap_Dst(dst).refresh();
            tdvTailorDim.setBitmap_Src(src).setBitmap_Dst(dst).setTransparency(70).refresh();
    
    • 先继承一个ImageView ,可以看到构造方法中只有initAttrs和initBitmap
    public class TailorDimView extends ImageView {
    //    private int DEF_HEIGHT = xxxx;
    
        private int Dst = 0;    //需要被裁剪什么形状  就传什么形状的图片   xml中使用
        private int Src = 0;   //源图片  xml中使用
        private Bitmap B_Dst;  //代码传入需要裁剪形状的图片
        private Bitmap B_Src;   //代码传入源图片
        private Integer transparency; //透明度  默认100(不透明)
        public TailorDimView(Context context) {
            this(context, null);
        }
    
        public TailorDimView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public TailorDimView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initAttrs(context, attrs, defStyleAttr);
            initBitmap();
        }
    
    
    • initAttrs(context, attrs, defStyleAttr) 获取资源, 需要注意的是 transparency 这个是设置图片的透明度的.获取方法是 .getInteger.上面两个方法是获取资源(也就是图片) 方法不一样 ,当时我就是在这弄了半天返回的一直是默认值....这块需要注意一下
    private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs,       R.styleable.TailorDimView, defStyleAttr, 0);
            //获取xml 中需要被裁剪形状的图片
            Dst = typedArray.getResourceId(R.styleable.TailorDimView_image_dst, 0);
            //获取xml 中源图片
            Src = typedArray.getResourceId(R.styleable.TailorDimView_image_src, 0);
            //透明度
            transparency = typedArray.getInteger(R.styleable.TailorDimView_trans, 100);
            typedArray.recycle();
        }
    
    • initBitmap() 这部分才是最关键的地方 ,具体的看注释就应该明白了
    private void initBitmap() {
            Bitmap bitmap_src = null;
            Bitmap bitmap_dst = null;
            //判断 有没有在代码中传入图片   优先级高于xml 设置
            if (null != B_Src && null != B_Dst){
                bitmap_src = B_Src;
                bitmap_dst = B_Dst;
                //代码没有设置  则获取xml中的图片
            }else if (Dst != 0 && Src != 0) {
                bitmap_dst = BitmapFactory.decodeResource(getResources(), Dst);
                saveBitmap(bitmap_dst,"bitmap_dst");
                bitmap_src = BitmapFactory.decodeResource(getResources(), Src);
                saveBitmap(bitmap_src,"bitmap_src");
            }else{
                //都没有 则抛出异常(英语是语文老师教的- -)
                Logger.e("bitmap_src and bitmap_dst is nul");
                throw new NullPointerException();
            }
            //用于设置  Canvas 的位图
            Bitmap W_H = Bitmap.createBitmap(bitmap_dst.getWidth(), bitmap_dst.getHeight(), Bitmap.Config.ARGB_8888);
    
            //设置画布
            Canvas canvas = new Canvas(W_H);
            //设置画笔
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            //设置 两张图片 覆盖的模式 (具体16中模式   百度---Canvas 覆盖模式)
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
            //如果透明度 不是 100  则代码设置
            if (transparency != 100)
                paint.setAlpha(transparency);
            //设置源图
            canvas.drawBitmap(bitmap_src, 0, 0, null);
            //设置裁剪图片
            canvas.drawBitmap(bitmap_dst, 0, 0, paint);
            //置空
            paint.setXfermode(null);
            //设置显示图片  记住 一定是你设定的 V_H   之前我一直使用bitmap_dst  一直显示裁剪不成功  切记切记
            setImageBitmap(W_H);
            saveBitmap(W_H,"merge");
            saveBitmap(bitmap_dst,"bitmap_dst___!");
            saveBitmap(bitmap_src,"bitmap_src___!");
        }
    
    • 大家应该看到了 savaBitmap 这是是我在测试的时候 看不同时候图片的形状
    public void saveBitmap(Bitmap bm,String picName) {
    
            File file = new File("/sdcard/song/");
            if(!file.exists())
                file.mkdirs();
            try {
                FileOutputStream fileOutputStream = new FileOutputStream(file.getPath() + "/"+picName+".jpg");
                bm.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
                fileOutputStream.close();
                System.out.println("saveBmp is here");
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    • 最终效果图 我这个是带有 透明度的
      这里写图片描述

    这是我第二次在CSDN中写博客 总感觉写的乱乱的 以后我会改改的,羡慕他们设计漂亮的博客

  • 相关阅读:
    Python金融量化分析小白入门篇之如何安装Tushare模块
    InvalidSpecError: Invalid spec: =2.7报错解决办法
    windows10安装集成环境wampserver,刚开始可以用图标是绿色的,但是过一段时间,启动后呈橙色,重启也不行
    Java代码写完如何打包成程序?.jar包如何转成.exe文件?
    C#通过虚方法实现多态性,具体要求如下:1、创建基类Cuboid(长方体)及带有三个参数(长、宽、高)的构造函数。2、使用virtual关键字创建Cuboid类的Cubage()方法(虚方法)。3、创建Cuboid类的派生类Cube(正方体),并使用override关键字创建与Cuboid类中同名的Cubage()方法,实现多态。
    用C#设计两个类,一个描述点,另一个描述圆。圆由圆心和半径构成,圆类由点类派生而来,其中圆心的特性描述由点类继承下来。要求:圆类提供求圆面积的成员函数;支持初始化的带参构造函数;取得圆心坐标的两个函数。
    C#程序填空题,根据注释内容,填补程序空白部分。
    在C#中readonly成员:判断对错。
    毕业设计第四次任务书
    毕业设计第三次任务书
  • 原文地址:https://www.cnblogs.com/guanhaoran/p/7243334.html
Copyright © 2020-2023  润新知