Android实现手势划定区域裁剪图片

本文实例为大家分享了Android实现手势划定区域裁剪图片的具体代码,供大家参考,具体内容如下

需求:

拍照,然后对图片进行处理,划定矩形区域,将矩形区域裁剪下来

思路:

1、使用系统相机拍照,拍完返回,对图片进行压缩和存储。

2、新建一个activity处理图片裁剪,利用自定义view在画布上画出矩形区域。

3、根据坐标信息生成裁剪图片并存储。

部分核心代码:

1、调用系统相机拍照

String IMAGE_PATH = Environment.getExternalStorageDirectory().getPath()+ "/com.kwmax.demo/Image/";
String filename = "xxxxxx.jpeg";
File picFile = new File(IMAGE_PATH + filename);
if (!picFile.exists()) {
    picFile.createNewFile();
}
 
...
if(getContext().getPackageManager().getLaunchIntentForPackage("com.sec.android.app.camera") != null) {
    cameraIntent.setPackage("com.sec.android.app.camera");
}
if (getContext().getPackageManager().getLaunchIntentForPackage("com.android.hwcamera") != null) {
    cameraIntent.setPackage("com.android.hwcamera");
}
if (getContext().getPackageManager().getLaunchIntentForPackage("com.zte.camera") != null) {
    cameraIntent.setPackage("com.zte.camera");
}
cameraIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); // 默认系统相机
cameraIntent.addCategory("android.intent.category.DEFAULT");
 
Uri pictureUri = Uri.fromFile(picFile);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, pictureUri);
startActivityForResult(intent, CAMERA_REQUEST_CODE);

2、自定义手势矩形view

public class CaptureRectView extends View {
    private int x;
    private int y;
    private int m;
    private int n;
    private boolean sign;//绘画标记位
    private Paint paint;//画笔
 
    public CaptureRectView (Context context) {
        super(context);
        paint = new Paint(Paint.FILTER_BITMAP_FLAG);
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        if(sign){
            paint.setColor(Color.TRANSPARENT);
        }else{
            paint.setColor(Color.RED);
            paint.setAlpha(80);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(15f);
            canvas.drawRect(new Rect(x, y, m, n), paint);
        }
        super.onDraw(canvas);
    }
 
    public void setSeat(int x,int y,int m,int n){
        this.x = x;
        this.y = y;
        this.m = m;
        this.n = n;
    }
 
    public boolean isSign() {
        return sign;
    }
 
    public void setSign(boolean sign) {
        this.sign = sign;
    }
}

3、裁剪页面布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/drawrect_framelayout"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@color/black"
                android:clickable="true"
                android:orientation="vertical">
 
    <RelativeLayout
        android:id="@+id/drawrect_relativelayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@color/black"
        android:orientation="vertical">
 
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/bottom">
            <LinearLayout
                android:id="@+id/image_zoom_view_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_centerInParent="true"
                android:gravity="center"
                android:orientation="vertical"/>
            <ImageView
                android:id="@+id/capture_preview"
                android:layout_width="80dp"
                android:layout_height="80dp"/>
        </FrameLayout>

        <LinearLayout
            android:id="@+id/bottom"
            android:layout_width="fill_parent"
            android:layout_height="50dip"
            android:layout_alignParentBottom="true"
            android:orientation="horizontal"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp">
 
            <Button
                android:id="@+id/btn_capture"
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_marginRight="10dp"
                android:text="裁剪"/>
 
            <Button
                android:id="@+id/btn_cancel"
                android:layout_width="50dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="取消"/>
 
        </LinearLayout>
 
    </RelativeLayout>
 
</FrameLayout>

4、裁剪activity

public class DrawRectActivity extends BasicActivity implements OnClickListener, View.OnTouchListener {
 
    private String TAG = "DrawRectActivity";
    private String imageString;
    private String imagePath;
    private ArrayList<String> imageList = null;
    private int position = 0;
    private int width, height;
    private LinearLayout layerViewLayout = null;
 
    private ImageView aiPreview;
    private CaptureRectView captureView;//绘画选择区域
    private int capX;//绘画开始的横坐标
    private int capY;//绘画开始的纵坐标
    private int capM;//绘画结束的横坐标
    private int capN;//绘画结束的纵坐标
    private Bitmap captureBitmap;
 
    private Button cancel;
    private Button aiCapture;
 
    private FrameLayout frameLayout;
    private RelativeLayout relativeLayout;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        init();
        initUI();
    }
 
    private void init() {
        width = ImageUtils.getScreenWidth(this);
        height = ImageUtils.getScreenHeight(this);
        Intent intent = this.getIntent();
        Bundle bundle = intent.getExtras();
        imageString = bundle.getString("imageString");
        imagePath = bundle.getString("imagePath");
        position = bundle.getInt("position");
        imageList = parseImageString(imagePath, imageString);
 
    }
 
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void initUI() {
        setContentView(R.layout.draw_image_rect_view);
        frameLayout = (FrameLayout) findViewById(R.id.drawrect_framelayout);
        relativeLayout = (RelativeLayout) findViewById(R.id.drawrect_relativelayout);
        layerViewLayout = (LinearLayout) this.findViewById(R.id.image_zoom_view_layout);
        btncancel = (Button) findViewById(R.id.btn_cancel);
        btnCapture = (Button) findViewById(R.id.btn_capture);
        btnPreview = (ImageView) findViewById(R.id.capture_preview);
 
        ImageView originImage = new ImageView(this);
        Bitmap image = ImageUtils.getBitmapFromFile(imagePath + imageList.get(position), 1);
        originImage.setImageBitmap(image);
        originImage.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        layerViewLayout.addView(originImage, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
 
        captureView = new CaptureRectView(this);
        originImage.setOnTouchListener(this);
        this.addContentView(captureView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
 
        if (frameLayout.isClickable()) {
            frameLayout.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                }
            });
        }
        btncancel.setOnClickListener(this);
        btnCapture.setOnClickListener(this);
 
    }
 
    private ArrayList<String> parseImageString(String imagePath, String imageString) {
        ArrayList<String> list = new ArrayList<String>();
        String allFiles = imageString.substring(imageString.indexOf("img://") + "img://".length());
        String fileName = null;
        while (allFiles.indexOf(";") > 0) {
            fileName = allFiles.substring(0, allFiles.indexOf(";"));
            allFiles = allFiles.substring(allFiles.indexOf(";") + 1);
            if (checkIsImageFile(fileName) && new File(imagePath + fileName).exists()) {
                list.add(fileName);
                Log.v("ParseImageString()", "imageName=" + fileName);
            } else {
                Log.v("ParseImageString()", "bad imageName=" + fileName);
            }
 
        }
        Log.v("ParseImageString()", "imagelist.size=" + list.size());
        return list;
    }
 
    /**
     * 判断是否相应的图片格式
     */
    private boolean checkIsImageFile(String fName) {
        boolean isImageFormat;
        if (fName.endsWith(".jpg") || fName.endsWith(".gif") || fName.endsWith(".png") || fName.endsWith(".jpeg") || fName.endsWith(".bmp")) {
            isImageFormat = true;
        } else {
            isImageFormat = false;
        }
        return isImageFormat;
    }
 
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                capX = 0;
                capY = 0;
                width = 0;
                height = 0;
                capX = (int) event.getX();
                capY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                capM = (int) event.getX();
                capN = (int) event.getY();
                captureView.setSeat(capX, capY, capM, capN);
                captureView.postInvalidate();
                break;
            case MotionEvent.ACTION_UP:
                if (event.getX() > capX) {
                    width = (int) event.getX() - capX;
                } else {
                    width = (int) (capX - event.getX());
                    capX = (int) event.getX();
                }
                if (event.getY() > capY) {
                    height = (int) event.getY() - capY;
                } else {
                    height = (int) (capY - event.getY());
                    capY = (int) event.getY();
                }
                captureBitmap = getCapturePreview(this);
                if (null != captureBitmap) {
                    btnPreview.setImageBitmap(captureBitmap);
                }
                break;
        }
        if (captureView.isSign()) {
            return false;
        } else {
            return true;
        }
    }
 
    private Bitmap getCapturePreview(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int toHeight = frame.top;
        //todo:这里需要针对部分机型做适配
        if (width > 0 && height > 0) {
            bitmap = Bitmap.createBitmap(bitmap, capX, capY + 240, width, height);
            view.setDrawingCacheEnabled(false);
            return bitmap;
        } else {
            return null;
        }
    }
 
    @Override
    public void onClick(View v) {
 
        switch (v.getId()) {
            case R.id.btn_cancel:
                Intent cancelintent = getIntent();
                createPendingResult(600, cancelintent, PendingIntent.FLAG_UPDATE_CURRENT);
                setResult(RESULT_OK, cancelintent);
                finish();
                break;
            case R.id.btn_capture:
                Intent sureintent = getIntent();
                createPendingResult(CpAIphotoAttributes.PHOTO_CAPTURE, sureintent, PendingIntent.FLAG_UPDATE_CURRENT);
                if (captureBitmap != null) {                  
                    try {
                        String file = IMAGE_PATH;
                        String randomid = UUID.randomUUID().toString();
                        String filename = randomid+ ".jpeg";
                        FileOutputStream fout = new FileOutputStream(file+filename);
                        captureBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fout);
                        sureintent.putExtra("capturePath", file+filename);
                        sureintent.putExtra("capturefilename", filename);
                        sureintent.putExtra("capturefileid", randomid);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                setResult(RESULT_OK, sureintent);
                finish();
                break;
            default:
                break;
        }
    }
 
 
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                Intent cancelintent = getIntent();
                createPendingResult(600, cancelintent, PendingIntent.FLAG_UPDATE_CURRENT);
                cancelintent.putExtra("imagePath", imagePath);
                cancelintent.putExtra("position", position);
                cancelintent.putExtra("todowhat", "cancel");
                setResult(RESULT_OK, cancelintent);
                finish();
                break;
            default:
                break;
        }
        return false;
    }
 
    @Override
    public void finish() {
        super.finish();
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case 400:
                    String text = null;
                    Log.v("DrawRectActivity", "onActivityReault imagePath=" + imagePath + imageList.get(position));
                    if (StringUtil.isNotBlank(text)) {
                        Log.v("DrawRectActivity", "onActivityReault imagePath=" + imagePath + imageList.get(position) + ";text=" + text);
                    } else {
 
                    }
                    break;
                default:
                    break;
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
 
    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android实现从本地图库/相机拍照后裁剪图片并设置头像

    玩qq或者是微信的盆友都知道,这些聊天工具里都要设置头像,一般情况下大家的解决办法是从本地图库选择图片或是从相机拍照,然后根据自己的喜爱截取图片.上述过程已经实现好了,最后一步我加上了把截取好的图片在保存到本地的操作,来保存头像.为了大家需要,下面我们小编把完整的代码贴出来供大家参考. 先给大家展示效果图: 代码部分: 布局代码(其实就是两个按钮和一个ImageView来显示头像) <LinearLayout xmlns:android="http://schemas.android.co

  • Android裁剪图片为圆形图片的实现原理与代码

    以前在eoe论坛中找过裁剪图片为圆形图片的方法,但是效果都不是很理想,这几天因为公司业务的要求,需要对头像进行裁剪以圆形的方式显示,这个方法是根据传入的图片的高度(height)和宽度(width)决定的,如果是 width <= height时,则会裁剪高度,裁剪的区域是宽度不变高度从顶部到宽度width的长度:如果 width > height,则会裁剪宽度,裁剪的区域是高度不变,宽度是取的图片宽度的中心区域,不过不同的业务需求,对裁剪图片要求不一样,可以根据业务的需求来调整裁剪的区域.

  • Android实现拍照、选择图片并裁剪图片功能

    一. 实现拍照.选择图片并裁剪图片效果 按照之前博客的风格,首先看下实现效果. 二. uCrop项目应用 想起之前看到的Yalantis/uCrop效果比较绚,但是研究源码之后发现在定制界面方面还是有一点的限制,于是在它的基础上做了修改Android-Crop,把定制界面独立出来,让用户去自由设置.下图为使用Android-Crop实现的模仿微信选择图片并裁剪Demo. 三. 实现思路 比较简单的选择设备图片裁剪,并将裁剪后的图片保存到指定路径: 调用系统拍照,将拍照图片保存在SD卡,然后裁剪图

  • Android 7.0中拍照和图片裁剪适配的问题详解

    前言 Android 7.0系统发布后,拿到能升级的nexus 6P,就开始了7.0的适配.发现在Android 7.0以上,在相机拍照和图片裁剪上,可能会碰到以下一些错误: Process: com.yuyh.imgsel, PID: 22995 // 错误1 android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.yuyh.imgsel/cache/1486438962645.jpg ex

  • Android实现图片区域裁剪功能

    今天做的就是关于实现图片的区域裁剪功能.由于项目功能的需要笔者需要实现PDF文档的阅读,并且就某个页面实现"图片"裁剪(一个页面理解为一张图片).笔者对着方面是一点儿也不熟悉,因此就得上网查资料了.之后笔者找到了Android可以通过调用系统相册.拍照实现图片的裁剪.缩放功能. 这一过程就像是在某个应用中上传头像,并对头像进行调整.现做一个记录与分享. 首先我们还是来看看实际的效果图吧! 一开始的界面: 接下来: 看看实际实现区域裁剪的效果吧?需要注意的是这是系统自带的功能来实现的.

  • Android编程实现调用系统图库与裁剪图片功能

    本文实例讲述了Android编程实现调用系统图库与裁剪图片功能.分享给大家供大家参考,具体如下: 在Android开发中,调用系统图库和裁剪照片是很常见的需求.相对于自己实现这种功能,直接调用系统具有诸多优点,如不用考虑屏幕适配,不用担心性能问题,等等.因此,对于一般的需求,建议直接调用系统的功能,简便高效! 首先上效果图:    一.只调用系统图库(不裁剪),返回用户选择的图片.(只支持单选,如需多选则需要自己实现,可参考Android编程实现仿QQ照片选择器(按相册分类显示,多选添加)源码.

  • 解决Android从相册中获取图片出错图片却无法裁剪问题的方法

    在学习获取相册中图片进行裁剪的时候遇到了比较大的问题,在纠结了近半天才真的解决,下面分享一下学习经验. 问题: 选择了相册中的图片之后要进入图片裁剪的时候出错,(华为)手机提示"此图片无法获取",经百度后,明白是版本不同导致的URI的问题的问题,原文如下: 4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4,如果使用上面pick的原生方法来选图,返回的uri还是正常的,但如果用ACTION_GET_CONTENT的方法,返回的uri跟4.3是完

  • Android拍照或从图库选择图片并裁剪

    今天看<第一行代码>上面关于拍照和从相册选取图片那一部分,发现始终出不来效果,所以搜索其他资料学习一下相关知识,写一个简单的Demo. 一. 拍照选择图片 1.使用隐式Intent启动相机 //构建隐式Intent Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //调用系统相机 startActivityForResult(intent, 1); 2.处理相机拍照返回的结果 //用户点击了取消 if(data == n

  • Android实现拍照及图片裁剪(6.0以上权限处理及7.0以上文件管理)

    最近做项目中涉及到了图片相关功能 ,在使用安卓6.0手机及7.1手机拍照时,遇到了因权限及文件管理导致程序崩溃等问题.  刚好把功能修改完,把代码简单地贴一下,方便以后使用. --主界面 代码 -- public class MainActivity extends AppCompatActivity { //拍照按钮 private Button take_photo; //显示裁剪后的图片 private ImageView photo_iv; private static final in

  • Android图片裁剪功能实现代码

    在Android应用中,图片裁剪也是一个经常用到的功能.Android系统中可以用隐式意图调用系统应用进行裁剪,但是这样做在不同的手机可能表现出不同的效果,甚至在某些奇葩手机上还会出其他更奇怪的问题,所以调用系统功能进行图片裁剪在很多时候对我们来说并不是一个好的选择.这时候就需要我们自己去实现这种裁剪功能了. 功能分析 要完成图片裁剪的功能,我们需要先知道图片裁剪的功能有哪些.图片裁剪之前,我们需要有一个框指示我们需要裁剪的样式合大小.图片显示出来后大小和位置可能并不是我们所期望的,所以我们还需

随机推荐