Android 高斯模糊 仿彩票刮奖效果 手动模糊图片

根据项目需要 需要这种需求 希望可以给一些有需求的朋友一点思路

我的思路是 先选取图片 通过高斯模糊 模糊图片 然后通过捕获触摸点 去设置图片的透明度 最后合成图片 达到部分清晰部分模糊的效果

下面直接上代码 在project的build.gradle关联远程库
allprojects {
repositories {
jcenter()
maven {url “https://jitpack.io“}
}
}
在app的build.gradle 添加依赖
compile ‘com.github.pinguo-zhouwei:EasyBlur:v1.0.0’
说一遍给一个xml 视图文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/easyblur_getpic"
        android:text="getPicture"/>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="200dp">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="50dp"
            android:scaleType="fitXY"
            android:id="@+id/easyblur_pic1"/>
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="50dp"
            android:scaleType="fitXY"
            android:id="@+id/easyblur_pic2"/>
    </FrameLayout>

</LinearLayout>

给两个imageview 分别显示清晰和模糊的图片

下面给出activity 文件 注释很清楚 大家自己看

/**
 *
 * 作者: Nade_S on 2018/4/19.
 * 高斯模糊 仿彩票刮奖功能
 *
 */

public class EasyBlurActivity extends BaseActivity{

    private String originPath;
    private Bitmap mOriginalBitmap;
    private ImageView blur_image;
    private ImageView iv_pre_image;
    private Bitmap beforeBitmap;
    private Canvas canvas;
    private int blurRadius = 12;
    private int eraseIndex=0;
    private boolean isFirstTouch=true;
    private Bitmap notBackBitmap;
    private HashMap<Integer,Bitmap> bitmapList=new HashMap<>();
    private AlertDialog blurDialog;
    private String mergePath;
    private String blurPath;
    private static final int width=4;
    private ImageView easyblur_pic1 , easyblur_pic2;

    @Override
    public void setContentView() {
        super.setContentView();
        setContentView(R.layout.activity_easyblur);
        easyblur_pic1 = (ImageView) findViewById(R.id.easyblur_pic1);
        easyblur_pic2 = (ImageView) findViewById(R.id.easyblur_pic2);
        findViewById(R.id.easyblur_getpic).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showImageFromDialog();
            }
        });
    }

    //底部弹窗 选择图片
    private void showImageFromDialog() {
        final Context context = this;
        AlertDialog.Builder b1 = new AlertDialog.Builder(context);
        View view = LayoutInflater.from(context).inflate(R.layout.picture_dialog, null);
        b1.setView(view);

        TextView camere = (TextView) view.findViewById(R.id.picdia_camere);
        TextView pic = (TextView) view.findViewById(R.id.picdia_pic);
        TextView cancel1 = (TextView) view.findViewById(R.id.picdia_cancel);

        final AlertDialog dialog1 = b1.create();
        Window window = dialog1.getWindow();
        camere.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String status= Environment.getExternalStorageState();
                if(status.equals(Environment.MEDIA_MOUNTED)){//判断是否有SD卡
                    // 从照相机获取
                    PictureUtils.takeCamera(EasyBlurActivity.this);
                    dialog1.dismiss();
                }
                else{
                    Toast.makeText(context, "没有SD卡", Toast.LENGTH_SHORT).show();
                }
            }
        });
        pic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 从相册中去获取
                PictureUtils.takeGallery();
                dialog1.dismiss();
            }
        });
        cancel1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog1.dismiss();
            }
        });
        dialog1.show();
        if (window!=null){
            window.setGravity(Gravity.BOTTOM);
        }

    }
    /*
       * 创建画布,画笔
       * */
    private void handlePic(ImageView imageView,Bitmap bitmap){
        Bitmap before = bitmap;
        beforeBitmap = Bitmap.createBitmap(before.getWidth(),
                before.getHeight(), before.getConfig());
        canvas = new Canvas(beforeBitmap);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas.drawBitmap(before, new Matrix(), paint);
        if (beforeBitmap !=null){
            imageView.setImageBitmap(beforeBitmap);
        }
    }
    /*
       * 模糊处理图片弹窗 持有bitmap 对象 从模糊到透明
       * */
    private void showBlurDialog(Bitmap imageBitmap){
        blurRadius=15;
        AlertDialog.Builder builder = null;
        builder = new AlertDialog.Builder(EasyBlurActivity.this);
        builder.setCancelable(true);
        View view = LayoutInflater.from(context).inflate(R.layout.blur_layout, null);
        builder.setView(view);//iv_imgsss
        final ImageView iv_back = (ImageView) view.findViewById(R.id.iv_back);
        blur_image = (ImageView) view.findViewById(R.id.iv_image);
        iv_pre_image = (ImageView)view.findViewById(R.id.iv_pre_image);
        final LinearLayout ll_guide = (LinearLayout) view.findViewById(R.id.ll_guide);
        iv_pre_image.setImageBitmap(imageBitmap);
        ImageView iv_cancel = (ImageView) view.findViewById(R.id.iv_cancel);
        ImageView iv_confirm = (ImageView) view.findViewById(R.id.iv_confirm);
        SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekBar);
        if (blurRadius>0){
            handlePic(blur_image,getBluredBitmap(imageBitmap,blurRadius));
        }

        //撤销模糊动作
        iv_back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (eraseIndex>0){
                    eraseIndex--;
                    //blur_image.setImageBitmap(bitmapList.get(eraseIndex));
                    if (notBackBitmap!=null){
                        beforeBitmap =notBackBitmap;
                    }
                    blur_image.setImageBitmap(getBluredBitmap(mOriginalBitmap,blurRadius));
                    if (eraseIndex==0){
                        iv_back.setImageResource(R.mipmap.last_light);
                    }
                }else {
                    showToast("无法撤销了");
                }
            }
        });
        //监听手指拖动改变透明度 捕获触摸点 设置透明
        blur_image.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (isFirstTouch){
                    notBackBitmap= beforeBitmap;
                }
                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_MOVE:
                        isFirstTouch=false;
                        int x = (int) motionEvent.getX();
                        int y = (int) motionEvent.getY();
                        int bitx = (int) (x/(blur_image.getWidth()/ beforeBitmap.getWidth()));
                        int bity = (int)(y/(blur_image.getHeight()/ beforeBitmap.getHeight()));
                        for (int i = bitx-width; i <= bitx+width; i++) {
                            for (int j = bity-width; j <=bity+ width; j++) {
                                if ( i >= 0 &&  j >= 0 &&  i < beforeBitmap.getWidth() &&j < beforeBitmap.getHeight()) {
                                    beforeBitmap.setPixel( i,  j, Color.TRANSPARENT);
                                }
                            }
                        }
                        blur_image.setImageBitmap(beforeBitmap);
                        break;
                    case MotionEvent.ACTION_UP:
                        eraseIndex++;
                        bitmapList.put(eraseIndex, beforeBitmap);
                        if (eraseIndex>0){
                            iv_back.setImageResource(R.mipmap.last_dark);
                        }
                        break;
                    case MotionEvent.ACTION_DOWN:
                        ll_guide.setVisibility(View.GONE);
                        break;
                }
                return true;
            }
        });
        //取消弹框
        iv_cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (blurDialog!=null){
                    blurDialog.dismiss();
                }
            }
        });
        //生成新的模糊图片,保存并展示在ui上
        iv_confirm.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {

                blurPath = CropPictures.saveBitmapFile(beforeBitmap,getPhotoFileName());

                easyblur_pic2.setImageBitmap(beforeBitmap);
                if (blurDialog!=null){
                    blurDialog.dismiss();
                }
                //生成合并图片并保存
                if (!TextUtils.isEmpty(originPath)&& beforeBitmap !=null){
                    Bitmap backgroundBitmap = BitmapFactory.decodeFile(originPath);
                    Bitmap foregroundBitmap= beforeBitmap;
                    Bitmap mergeBitmap = mergeThumbnailBitmap(backgroundBitmap, foregroundBitmap);
                    mergePath = CropPictures.saveBitmapFile(mergeBitmap,getPhotoFileName());
                }

            }
        });
        //监听seekbar的拖动,改变整体透明度
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                blurRadius = i;
                Log.d("tag","模糊率="+i);
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                eraseIndex=0;
                bitmapList.clear();
                iv_back.setImageResource(R.mipmap.last_light);
                if (blur_image !=null){
                    if (blurRadius>0){
                        handlePic(blur_image,getBluredBitmap(mOriginalBitmap,blurRadius));
                    }
                }
            }
        });


        blurDialog = builder.create();
        blurDialog.show();
        eraseIndex=0;
        bitmapList.clear();
    }
    /*
    * 高斯 模糊图片
    * */
    private Bitmap getBluredBitmap(Bitmap originBitmap,int blurRadius){
        Bitmap finalBitmap;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){//api大于17采用renderscript模糊
            finalBitmap = EasyBlur.with(EasyBlurActivity.this)
                    .bitmap(originBitmap) //要模糊的图片
                    .radius(blurRadius)//模糊半径
                    .scale(4)//指定模糊前缩小的倍数
                    .policy(EasyBlur.BlurPolicy.RS_BLUR)//使用renderscript
                    .blur();
        }else {
            finalBitmap = EasyBlur.with(EasyBlurActivity.this)
                    .bitmap(originBitmap) //要模糊的图片
                    .radius(blurRadius)//模糊半径
                    .scale(4)//指定模糊前缩小的倍数
                    .policy(EasyBlur.BlurPolicy.FAST_BLUR)//使用fastBlur
                    .blur();
        }
        return finalBitmap;
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK)
            return;
        originPath = FileUtils.getFileName();
        switch (requestCode) {
            case PictureUtils.TYPE_CAMERE:
                //压缩图片 返回bitmap 对象
                mOriginalBitmap = BitmapUtils.getSmallBitmap(PictureUtils.out.getAbsolutePath(), 480, 480,new File(originPath));
                clearImageView();
                easyblur_pic2.setImageBitmap(mOriginalBitmap);
                easyblur_pic1.setImageBitmap(mOriginalBitmap);
                showBlurDialog(mOriginalBitmap);
                break;
            case PictureUtils.TYPE_GALLERY:
                mOriginalBitmap = BitmapUtils.getSmallBitmap(PictureUtils.getRealPathFromURI(EasyBlurActivity.this, data.getData()), 480, 480,new File(originPath));
                clearImageView();
                easyblur_pic2.setImageBitmap(mOriginalBitmap);
                easyblur_pic1.setImageBitmap(mOriginalBitmap);
                showBlurDialog(mOriginalBitmap);
                break;
        }

    }
    public void clearImageView() {
        if (easyblur_pic2!=null){
            easyblur_pic2.setImageBitmap(null);
        }
        if (blur_image !=null){
            blur_image.setImageBitmap(null);
        }
    }


    // 以当前时间给图片命名
    public String getPhotoFileName() {
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat dateFormat = new SimpleDateFormat("'IMG'_yyyyMMddHHmmss");
        return dateFormat.format(date) + ".jpg";
    }


    /*
        * 合并两张图片为一张
        * */
    private Bitmap mergeThumbnailBitmap(Bitmap background, Bitmap foreground) {
        //以其中一张图片的大小作为画布的大小,或者也可以自己自定义
        Bitmap bitmap = Bitmap.createBitmap(background.getWidth(), background
                .getHeight(), background.getConfig());
        //生成画布
        Canvas canvas = new Canvas(bitmap);
        //因为我传入的secondBitmap的大小是不固定的,所以我要将传来的secondBitmap调整到和画布一样的大小
        float w = background.getWidth();
        float h = background.getHeight();
        Matrix m = new Matrix();
        //确定secondBitmap大小比例
        m.setScale(w / foreground.getWidth(), h / foreground.getHeight());
        Paint paint = new Paint();
        //给画笔设定透明值,想将哪个图片进行透明化,就将画笔用到那张图片上
        paint.setAlpha(255);
        canvas.drawBitmap(background, 0, 0, null);
        canvas.drawBitmap(foreground, m, paint);

        return bitmap;
    }

}

相机相册选择图片我就不在这里给出了 压缩图片的方法 本人也有文章 你可以自己去看一下 https://blog.csdn.net/naide_s/article/details/79840320 图片压缩

说在最后 如果报错 java.lang.NoClassDefFoundError: Failed resolution of: Landroid/support/v8/renderscript/RenderScript;
不要担心 找到你的sdk Android\Sdk\build-tools\21.1.1\renderscript\lib 这个路径下的 renderscript-v8,jar 复制到你项目的libs 文件夹下 同步完成就可以了

猜你喜欢

转载自blog.csdn.net/naide_s/article/details/80009982