精华内容
下载资源
问答
  • 这里写自定义目录标题调用方式基本配置权限providerfile_path封装 BasePhotoActivity Kotlin底部弹框 PopupWindow动画样式 stylesalpha_inalpha_out裁剪方法 关于 demo案例 ,参考github ...

    github地址 https://github.com/JI577/ChoosePicture

    调用方式

    class MainActivity : BasePhotoActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            tvPic.setOnClickListener {
                if (checkPermission()) {
                    showDialog()
                }
            }
        }
        override fun showDialog() {
            getPopView().showAtLocation(llAll, Gravity.BOTTOM, 0, 0)
        }
    
        override fun getHeadNet(file: File) {
            Log.e("jrq", "File path----" + file.absolutePath)
            tvContent.text = file!!.absolutePath
        }
    }
    

    基本配置

    权限

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.CAMERA" />
    

    provider

    <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.wj577.choosepicture.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_path" />
        </provider>
    

    file_path

     <?xml version="1.0" encoding="utf-8"?>
     <paths xmlns:android="http://schemas.android.com/apk/res/android">
     <external-path name="rc_external_path" path="."/>
    

    封装 BasePhotoActivity Kotlin

    open abstract class BasePhotoActivity : FragmentActivity() {
    
        private val REQUESTCODE_PICK = 0x121        // 相册选图标记
        val RESULT_COD = 102
    
        var picDialog: SelectPicPopupwindow? = null
        private val mFile_Pic: File? = null// 存储图片的文件
        private val permissions = arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)
    
        private var dialog: AlertDialog? = null
        private var mBitmap: Bitmap? = null
    
    
        fun getPopView(): SelectPicPopupwindow {
            if (null == picDialog) {
                headPic()
            }
                return picDialog!!
        }
    
        fun checkPermission(): Boolean {
            // 版本判断。当手机系统大于 23 时,才有必要去判断权限是否获取
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                for (permission in permissions) {
                    // 检查该权限是否已经获取
                    val i = ContextCompat.checkSelfPermission(this, permission)
                    // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
                    if (i != PackageManager.PERMISSION_GRANTED) {
                        // 如果没有授予该权限,就去提示用户请求
                        showDialogTipUserRequestPermission()
    
                        return false
                    }
                }
            }
            return true
        }
    
        fun showDialogTipUserRequestPermission() {
            AlertDialog.Builder(this)
                    .setTitle("存储权限不可用")
                    .setMessage("由于选取照片和拍照需要手机的部分权限,否则您将不能使用该应用的全部功能")
                    .setPositiveButton("立即开启") { dialog, which -> startRequestPermission() }
                    .setNegativeButton("取消") { dialog, which -> finish() }.setCancelable(false).show()
        }
    
        fun startRequestPermission() {
            ActivityCompat.requestPermissions(this, permissions, 321)
        }
    
        override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            if (requestCode == 321) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                        // 判断用户是否 点击了不再提醒。(检测该权限是否还可以申请)
                        val b = shouldShowRequestPermissionRationale(permissions[0])
                        if (!b) {
                            // 用户还是想用我的 APP 的
                            // 提示用户去应用设置界面手动开启权限
                            showDialogTipUserGoToAppSettting()
                        } else
                            finish()
                    } else {
    
    //                    picDialog!!.showAtLocation(llAll, Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)
                        showDialog()
                    }
                }
            }
        }
    
        fun showDialogTipUserGoToAppSettting() {
            dialog = AlertDialog.Builder(this)
                    .setTitle("存储权限不可用")
                    .setMessage("请在-应用设置-权限-中,允许本应用使用相机的相应权限来启用拍照等功能")
                    .setPositiveButton("立即开启") { dialog, which ->
                        // 跳转到应用设置界面
                        goToAppSetting()
                    }
                    .setNegativeButton("取消") { dialog, which -> finish() }.setCancelable(false).show()
        }
    
        fun headPic() {
            picDialog = SelectPicPopupwindow(this, View.OnClickListener { v ->
                when (v.id) {
                    //拍照
                    R.id.btn_take_photo -> getPicCamera()
                    //相册
                    R.id.btn_pick_photo -> selectPicture()
                }
                picDialog!!.dismiss()
            }, SelectPicPopupwindow.PHOTO)
    
        }
    
        private var mPictureFile: String? = null
        private var filePath: String? = null
        private val OPEN_RESULT2 = 0x124 // 打开相机2
    
        fun getPicCamera() {
            val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            intent.addCategory(Intent.CATEGORY_DEFAULT)
            // 取当前时间为照片名
            mPictureFile = DateFormat.format("yyyyMMdd_hhmmss",
                    Calendar.getInstance(Locale.CHINA)).toString() + ".jpg"
            //        Log.d("onactivity", "mPictureFile:" + mPictureFile);
            filePath = getPhotoPath() + mPictureFile!!
            //        mFile_Pics[position] = getPhotoPath() + mPictureFile;
            //        // 通过文件创建一个uri中
            //        Uri imageUri = Uri.fromFile(new File(filePath));
            //        // 保存uri对应的照片于指定路径
            //        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            //        startActivityForResult(intent, OPEN_RESULT2);
    
            /*获取当前系统的android版本号*/
            val currentapiVersion = android.os.Build.VERSION.SDK_INT
            Log.e("jrq", "currentapiVersion====>$currentapiVersion")
            if (currentapiVersion < 24) { // 保存uri对应的照片于指定路径
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(File(filePath!!)))
                startActivityForResult(intent, OPEN_RESULT2)
            } else {
                val contentValues = ContentValues(1)
                contentValues.put(MediaStore.Images.Media.DATA, filePath)
                val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
                intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
                startActivityForResult(intent, OPEN_RESULT2)
            }
        }
    
        /**
         * 获得照片路径
         *
         * @return
         */
        fun getPhotoPath(): String {
            return Environment.getExternalStorageDirectory().toString() + "/DCIM/"
        }
    
        fun goToAppSetting() {
            val intent = Intent()
            intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
            val uri = Uri.fromParts("package", packageName, null)
            intent.data = uri
            startActivityForResult(intent, 123)
        }
    
        /**
         * 选择图片
         */
        fun selectPicture() {
            val intent = Intent()
            intent.action = Intent.ACTION_PICK//Pick an item from the data
            intent.type = "image/*"//从所有图片中进行选择
            startActivityForResult(intent, REQUESTCODE_PICK)
        }
    
    
        override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
            super.onActivityResult(requestCode, resultCode, data)
    
            if (requestCode == RESULT_COD) {//裁剪
    //            if (data != null) {
    //                setPicParam(data)
    //            }
                setPicParam()
            }
    
            /**修改相机 */
            if (requestCode == OPEN_RESULT2) {
                if (resultCode == Activity.RESULT_OK) {
                    var uri: Uri? = null
                    if (Build.VERSION.SDK_INT >= 24) {
                        uri = FileProvider.getUriForFile(this, packageName + ".FileProvider", File(filePath))
                    } else {
                        uri = Uri.fromFile(File(filePath))
                    }
                    startPhotoZoom(uri)
                }
            }
    
            if (resultCode == Activity.RESULT_OK)
                when (requestCode) {
                    REQUESTCODE_PICK//相册
                    -> startPhotoZoom(data!!.data)
                }
    
        }
        var uritempFile :Uri?=null
    
        private fun startPhotoZoom(uri: Uri) {
            val intent = Intent("com.android.camera.action.CROP")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            }
            intent.setDataAndType(uri, "image/*")
            //是否可裁剪
            intent.putExtra("corp", "true")
            //裁剪器高宽比
            intent.putExtra("aspectY", 1)
            intent.putExtra("aspectX", 1)
            //设置裁剪框高宽
            intent.putExtra("outputX", 300)
            intent.putExtra("outputY", 300)
            //返回数据
    //        intent.putExtra("return-data", true)
    
             uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    
    
            startActivityForResult(intent, RESULT_COD)
        }
    
        private fun setPicParam(data: Intent) {
            val bundle = data.extras
            if (bundle != null) {
                mBitmap = bundle.getParcelable<Bitmap>("data")
    
                Log.e("jrq","---mBitmap-------"+mBitmap)
                val file = compressImage(mBitmap!!)
                if (file.exists()) {
                    getHeadNet(file)
                }
            }
    
        }
    
        private fun setPicParam() {
                  mBitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile));
                Log.e("jrq","---mBitmap-------"+mBitmap)
                val file = compressImage(mBitmap!!)
                if (file.exists()) {
                    getHeadNet(file)
                }
    
        }
    
        fun compressImage(bitmap: Bitmap): File {
            val baos = ByteArrayOutputStream()
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
            var options = 100
            while (baos.toByteArray().size / 1024 > 500) {  //循环判断如果压缩后图片是否大于500kb,大于继续压缩
                baos.reset()//重置baos即清空baos
                options -= 10//每次都减少10
                bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos)//这里压缩options%,把压缩后的数据存放到baos中
                val length = baos.toByteArray().size.toLong()
            }
            val format = SimpleDateFormat("yyyyMMddHHmmss")
            val date = Date(System.currentTimeMillis())
            val filename = format.format(date)
            val file = File(Environment.getExternalStorageDirectory(), "$filename.png")
            try {
                val fos = FileOutputStream(file)
                try {
                    fos.write(baos.toByteArray())
                    fos.flush()
                    fos.close()
                } catch (e: IOException) {
    
                    e.printStackTrace()
                }
    
            } catch (e: FileNotFoundException) {
                Log.e("jrq", e.message)
                e.printStackTrace()
            }
    
            recycleBitmap(bitmap)
            return file
        }
    
        fun recycleBitmap(vararg bitmaps: Bitmap) {
            if (bitmaps == null) {
                return
            }
            for (bm in bitmaps) {
                if (null != bm && !bm.isRecycled) {
                    bm.recycle()
                }
            }
        }
    
        abstract fun showDialog()
        abstract fun getHeadNet(file: File)
    }
    

    底部弹框 PopupWindow

    public class SelectPicPopupwindow extends PopupWindow {
        private TextView btn_take_photo, btn_pick_photo, btn_cancel;
        private View mMenuView;
    
        public SelectPicPopupwindow(Context context, OnClickListener itemsOnClick, int option) {
            super(context);
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            mMenuView = inflater.inflate(R.layout.photo_window_view, null);
            
            btn_take_photo = (TextView) mMenuView.findViewById(R.id.btn_take_photo);
            btn_pick_photo = (TextView) mMenuView.findViewById(R.id.btn_pick_photo);
            btn_cancel = (TextView) mMenuView.findViewById(R.id.btn_cancel);
            // 取消按钮
            btn_cancel.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    // 销毁弹出框
                    dismiss();
                }
            });
            // 设置按钮监听
            btn_pick_photo.setOnClickListener(itemsOnClick);
            btn_take_photo.setOnClickListener(itemsOnClick);
            // 设置SelectPicPopupWindow的View
            this.setContentView(mMenuView);
            // 设置SelectPicPopupWindow弹出窗体的宽
            this.setWidth(LayoutParams.MATCH_PARENT);
            // 设置SelectPicPopupWindow弹出窗体的高
            this.setHeight(LayoutParams.WRAP_CONTENT);
            // 设置SelectPicPopupWindow弹出窗体可点击
            this.setFocusable(true);
            // 设置SelectPicPopupWindow弹出窗体动画效果
            this.setAnimationStyle(R.style.popupAnimation);
            // 实例化一个ColorDrawable颜色为半透明
            ColorDrawable dw = new ColorDrawable(0xaa000000);
            // 设置SelectPicPopupWindow弹出窗体的背景
            this.setBackgroundDrawable(dw);
            // mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框
        }
    }
    

    动画样式 styles

        <!--淡入淡出popupwindow -->
        <style name="popupAnimation" parent="android:Animation">
            <item name="android:windowEnterAnimation">@anim/alpha_in</item>
            <item name="android:windowExitAnimation">@anim/alpha_out</item>
        </style>
    
    alpha_in
    <?xml version="1.0" encoding="utf-8"?>  
    <set xmlns:android="http://schemas.android.com/apk/res/android">  
       <alpha  
       android:fromAlpha="0.0"
       android:toAlpha="0.5"
       android:duration="0"
       />
       <translate
           android:duration="0"
           android:fromYDelta="100%p"
           android:toYDelta="0" />
    </set>
        <!--  
        fromAlpha:开始时透明度  
        toAlpha:结束时透明度  
        duration:动画持续时间   
        淡入
         -->  
    
    alpha_out
    <?xml version="1.0" encoding="utf-8"?>  
    <set xmlns:android="http://schemas.android.com/apk/res/android">
       <translate
           android:duration="0"
           android:fromYDelta="0"
           android:toYDelta="50%p" />
       <alpha
           android:duration="0"
           android:fromAlpha="0.5"
           android:toAlpha="0.0" />
    </set>  
    <!--  
    fromAlpha:开始时透明度  
    toAlpha:结束时透明度  
    duration:动画持续时间  
    淡出
     -->  
    

    裁剪方法

    
      private fun startPhotoZoom(uri: Uri) {
              val intent = Intent("com.android.camera.action.CROP")
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            }
       
         //intent.setDataAndType(uri, "image/*")
            //是否可裁剪
            intent.putExtra("corp", "true")
            //裁剪器高宽比
            intent.putExtra("aspectY", 1)
            intent.putExtra("aspectX", 1)
            //设置裁剪框高宽
            intent.putExtra("outputX", 300)
            intent.putExtra("outputY", 300)
            //返回数据
            intent.putExtra("return-data", true)
            uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");
            intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
            startActivityForResult(intent, RESULT_COD)
        }
    
    
    展开全文
  • 前情说明 ...我这里出现的问题是选择图片在小米手机出现crash,拍照图片无法加载,而其他手机则正常。 使用FileProvider构建的Uri是以Content://开头的,而使用Uri.fromFile()创建的是以file:/...

    前言

    众所周知Android7.0提高了安全防护,不允许应用内部Uri暴露给外部,因此引入了FileProvider。有关FileProvider的使用和配置,这里就不赘述了。我这里出现的问题是选择图片在小米手机出现crash,拍照图片无法加载,而其他手机则正常。

    • 使用FileProvider构建的Uri是以Content://开头的,而使用Uri.fromFile()创建的是以file:///开头的;

    代码出现bug

    图片裁剪代码如下:

    private boolean corp(Activity activity, Uri uri) {
            Intent cropIntent = new Intent("com.android.camera.action.CROP");
            cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            cropIntent.setDataAndType(uri, "image/*");
            cropIntent.putExtra("crop", "true");
            cropIntent.putExtra("aspectX", 1);
            cropIntent.putExtra("aspectY", 1);
            cropIntent.putExtra("outputX", 200);
            cropIntent.putExtra("outputY", 200);
            cropIntent.putExtra("noFaceDetection", true);
            cropIntent.putExtra("return-data", false);
            cropIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
    
            File dir = new File(Environment.getExternalStorageDirectory().getPath() , "avatar_image");
            if (!dir.exists() && dir.mkdirs()) ;
            File fileCrop  = new File(dir, CROP_FILE_NAME);
            if (!fileCrop.exists()) {
                try {
                    fileCrop.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            cropImageUri = Uri.fromFile(fileCrop);
            cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, cropImageUri);
            activity.startActivityForResult(cropIntent, INTENT_CROP);
        }
    
    1. 选择图片报错
    Caused by: java.lang.SecurityException: Uid 10797 does not have permission to uri 0 @ content://com.miui.gallery.open/raw/...20180921_202403.jpg
    

    这里的Uri已经是Gallery产生的了,为什么还是报错呢?
    看有帖子说是需要去掉intent.addFlag即可。

    1. 于是我照做了,但是Camera拍照又出现问题了:弹出toast无法加载此图片

    思考为什么:

    Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
    

    这个flag为Intent赋予了临时权限,允许读写传入的uri,也就是被裁剪的图片文件;

    • 拍照时Uri是FileProvider生成的:content://com.xxx.packagename/avatar_image/photo_file.jpg,是应用内部文件,对外开放需要临时权限;
    • 选择图片Uri是:content://com.miui.gallery.open/raw/...,是小米相册ContentProvider生成的,因此对所有应用开放,不需要临时权限。
    • 裁剪是该应用调用系统裁剪接口,是从本应用去到外部应用;
      因此这里的Uri需要区别对待:
       private boolean corp(Activity activity, Uri uri, boolean fromCamera) {
            Intent cropIntent = new Intent("com.android.camera.action.CROP");
            if (fromCamera){
                cropIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            }
           ...
    

    至此,该问题解决

    总结:

    1. 如果是App内部Uri,需要通过FileProvider构建和暴露给外部,并添加临时权限;如果不是App内部的,则不必添加临时权限;关键:明确资源来源,和资源去向
    2. Android不断提升的安全和权限限制,例如 Android 9.0建议使用HTTPS访问,不然会抛出异常java.net.UnknownServiceException: CLEARTEXT communication ** not permitted by network security policy;因此安卓为开发者提出了更多更高要求,需要开发者不断提高安全意识,也令应用开发不断规范化,为安卓点赞!
    展开全文
  • 小记 有些手机裁剪图片问题

    千次阅读 2014-01-06 17:40:34
    android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.android.camera.action.CROP dat=file:///storage/sdcard0/201401_06143603.jpg typ=image/* (has extras) } ...



    android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.android.camera.action.CROP dat=file:///storage/sdcard0/201401_06143603.jpg typ=image/* (has extras) }

     可以使用以下链接给的一个第三方库(还未测试)

    http://stackoverflow.com/questions/18013406/is-com-android-camera-action-crop-not-available-for-android-jelly-bean-4-3


     //注意一个问题  需要注册

     <activity android:name="eu.janmuller.android.simplecropimage.CropImage" />


     然后用了这个,打包的时候会出一个问题

    "app_name" is not translated in cs ,

     

    解决方法

      http://blog.csdn.net/janronehoo/article/details/15809423

     看这个链接我只是把那个修改成warning  工程不报错了,但是再次打包还是出问题,

     最后解决方法是, 把simple-crop-image-lib 中的 values-cs 删除掉。。。。 。  若是要考虑多种语言的,就不能这么干了..

    展开全文
  • 手机拍照及裁剪图片

    千次阅读 2016-10-10 15:26:40
    手机拍照及裁剪图片

    注:我是在上一篇博客:“手机拍照及简单的图片压缩”的基础上改的,所以,权限等,参考上一篇,这里只对核心代码做说明
    图片被裁剪后,清晰度不够,这个问题我没解决
    1、效果图:

    这里写图片描述

    这里写图片描述

    2、代码:
    2.1:全局变量:

    /**
     * 用于保存全局变量值
     */
    public class CHEN {
    
        /**
         * 裁剪后图片保存的地址
         */
        public static String crop_img_path = Environment.getExternalStorageDirectory() + "/chen/crop";
    
        /**
         * 拍照的返回请求码
         */
        public static int TakePhotoRequestCode = 123;
    
        /**
         * 裁剪的返回请求码
         */
        public static int CropImgRequestCode = 234;
    
    }

    2.2:布局:activity_main_22

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  android:background="#F6F6F6"
                  android:fitsSystemWindows="true"
                  android:orientation="vertical">
    
        <RelativeLayout
            android:id="@+id/search_gold_expert_back_title"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="#ec434b"
            android:gravity="center_vertical"
            android:orientation="horizontal">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="点击icon"
                android:textColor="#ffffff"
                android:textSize="20sp"/>
    
        </RelativeLayout>
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:overScrollMode="never"
            android:scrollbars="none">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                >
    
                <ImageView
                    android:id="@+id/iv_image"
                    android:layout_width="310dp"
                    android:layout_height="250dp"
                    android:layout_gravity="center_horizontal"
                    android:layout_margin="10dp"
                    android:src="@mipmap/ic_launcher"/>
    
                <TextView
                    android:id="@+id/confirm_tv"
                    android:layout_width="fill_parent"
                    android:layout_height="38dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:background="#ec434b"
                    android:gravity="center"
                    android:onClick="onClick"
                    android:text="提交"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:lineSpacingMultiplier="1.4"
                    android:text="拍照得到照片的原路径"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
                <TextView
                    android:id="@+id/result_url_tv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:lineSpacingMultiplier="1.4"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:lineSpacingMultiplier="1.4"
                    android:text="拍照得到照片的大小"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
                <TextView
                    android:id="@+id/photo_src_size"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:lineSpacingMultiplier="1.4"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:lineSpacingMultiplier="1.4"
                    android:text="裁剪后的图片的路径"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
                <TextView
                    android:id="@+id/crop_img_path"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:lineSpacingMultiplier="1.4"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:lineSpacingMultiplier="1.4"
                    android:text="裁剪后照片的大小"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
                <TextView
                    android:id="@+id/crop_img_size"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="20dp"
                    android:layout_marginLeft="10dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginTop="10dp"
                    android:lineSpacingMultiplier="1.4"
                    android:textColor="#4F4F4F"
                    android:textSize="16sp"/>
    
            </LinearLayout>
    
        </ScrollView>
    
    </LinearLayout>

    2.3:主代码:MainActivity_22_Photo_Crop_Img

    
    /**
     * 拍照,并裁剪图片
     */
    public class MainActivity_22_Photo_Crop_Img extends BaseActivity implements View.OnClickListener, PopSelectListener {
    
        ImageView iv_image;
        TextView confirm_tv;
        TextView result_url_tv;
        TextView photo_src_size;
    
        TextView crop_img_path;
        TextView crop_img_size;
    
        PhotoFromSelectPop photoFromSelectPop;
    
        String url;
        String imageName;
    
        @Override
        void initview() {
            setContentView(R.layout.activity_main_22);
    
            iv_image = (ImageView) findViewById(R.id.iv_image);
            confirm_tv = (TextView) findViewById(R.id.confirm_tv);
            result_url_tv = (TextView) findViewById(R.id.result_url_tv);
            photo_src_size = (TextView) findViewById(R.id.photo_src_size);
    
            crop_img_path = (TextView) findViewById(R.id.crop_img_path);
            crop_img_size = (TextView) findViewById(R.id.crop_img_size);
    
            iv_image.setOnClickListener(this);
            confirm_tv.setOnClickListener(this);
    
            File file = new File(CHEN.img_path);
            if (!file.exists()) {
                try {
                    file.mkdirs();
                    Toast.makeText(this, "路径创建成功", Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    Toast.makeText(this, "路径创建失败", Toast.LENGTH_SHORT).show();
                }
            }
        }
    
        @Override
        public void onClick(View v) {
    
            switch (v.getId()) {
                case R.id.iv_image:
    
                    photoFromSelectPop = new PhotoFromSelectPop(this);
                    photoFromSelectPop.initPopupWindow(this);
    
                    break;
                case R.id.confirm_tv:
    
                    break;
            }
    
        }
    
        @Override
        public void popSelect(int flag) {
    
            switch (flag) {
                case 0:
    
                    Toast.makeText(this, "从相册选取", Toast.LENGTH_SHORT).show();
    
                    break;
    
                case 1:
                    //拍照
                    imageName = "/" + System.currentTimeMillis() + ".jpg";
                    Intent intent_photo = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent_photo.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(CHEN.img_path, imageName)));
                    startActivityForResult(intent_photo, CHEN.TakePhotoRequestCode);
                    break;
    
            }
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
            Log.e("requestCode", requestCode + "");
            Log.e("resultCode", resultCode + "");
    
            if (CHEN.TakePhotoRequestCode == requestCode) {
                url = CHEN.img_path + imageName;
                if (!TextUtils.isEmpty(url)) {
                    result_url_tv.setText(url);
                    File file = new File(url);
                    photo_src_size.setText("图片大小==KB==" + Utils.getNumAccuracy_2(file.length() / 1024f) + "---图片大小==MB==" + Utils.getNumAccuracy_2(file.length() / (1024f * 1024f)));
                    cropImage(file);
    
                }
            }
    
            if (CHEN.CropImgRequestCode == requestCode) {
                try {
                    if (data != null) {
                        Bitmap bitmap_crop = data.getParcelableExtra("data");
                        //裁剪的图片保存到本地
                        File cropedfile = saveCroppedImage(bitmap_crop);
                        crop_img_path.setText(cropedfile.getPath());
                        crop_img_size.setText("图片大小==KB==" + Utils.getNumAccuracy_2(cropedfile.length() / 1024f));
                    } else {
                        Toast.makeText(this, "取消裁剪", Toast.LENGTH_SHORT).show();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
    
                }
            }
            super.onActivityResult(requestCode, resultCode, data);
        }
    
        /**
         * 裁剪照片
         *
         * @param file
         */
        private void cropImage(File file) {
            Uri mUri = Uri.fromFile(file);
            if (null == mUri)
                return;
            Intent intent = new Intent("com.android.camera.action.CROP");
            intent.setDataAndType(mUri, "image/*");// mUri是已经选择的图片Uri
            intent.putExtra("crop", "true");// crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
            //宽高比例
            intent.putExtra("aspectX", 2);
            intent.putExtra("aspectY", 1.9);
            // outputX outputY 是裁剪图片宽高
            intent.putExtra("outputX", 150);
            intent.putExtra("outputY", 150);
            intent.putExtra("outputFormat", "JPEG");
            intent.putExtra("scale", true);
            intent.putExtra("noFaceDetection", true);
            //若为false则表示不返回数据
            intent.putExtra("return-data", true);
            startActivityForResult(intent, CHEN.CropImgRequestCode);
        }
    
        /**
         * bitmap保存到本地
         *
         * @param bmp
         */
        private File saveCroppedImage(Bitmap bmp) {
            File file = new File(CHEN.crop_img_path);
            if (!file.exists())
                file.mkdir();
    
            file = new File(CHEN.crop_img_path + "/" + "crop_temp.jpg");
            String fileName = file.getName();
            String mName = fileName.substring(0, fileName.lastIndexOf("."));
            String sName = fileName.substring(fileName.lastIndexOf("."));
    
            Log.e("mName", mName);
            Log.e("sName", sName);
    
            //裁剪后的图片的地址
            String newFilePath = CHEN.crop_img_path + "/" + mName + "_cropped" + sName;
            file = new File(newFilePath);
            try {
                file.createNewFile();
                FileOutputStream fos = new FileOutputStream(file);
                bmp.compress(Bitmap.CompressFormat.PNG, 100, fos);
                fos.flush();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return file;
        }
    }
    
    展开全文
  • cropper.js 实现HTML5 裁剪图片并上传(裁剪上传头像。)

    万次阅读 多人点赞 2016-07-04 19:43:38
    我的需求功能:在手机端实现上传头像,带裁剪框。 cropper.js 通过canvas实现图片裁剪,最后在通过canvas获取裁剪区域的图片base64串。 cropper 文档:官方文档是全英文的,好吧我看不懂。只能一个个试试效果,就...
  • AlloyCrop手机移动端图片裁剪组件代码 AlloyCrop手机移动端图片裁剪组件代码
  • PHP支持手势的手机图片裁剪上传 PHP支持手势的手机图片裁剪上传
  • html5手机图片上传裁剪代码是一款实用的手机移动端图片裁剪插件,支持缩放。
  • html5微信手机图片上传裁剪代码是一款实用的手机移动端图片裁剪插件,支持缩放。
  • 这是一个通过cropper.js做的手机移动端的图片相片裁剪,触摸使用的
  • 通过获取手机图片然后调用系统裁剪分享。
  • ThinkPHP,手机端注册页面,上传头像(裁剪后并且上传),点击提交后,提示“上传文件后缀不允许”,输出了结果发现type是application/octet-stream。 同样的页面在pc端运行正常,请问这种情况该怎么处理,怎样才能...
  • jQuery.photoClip手机图片裁剪插件
  • html5手机上传图片尺寸裁剪代码是一款支持微信,手机网站拍照上传,质量太高可压缩图片尺寸质量。
  • html5手机图片上传裁剪代码是一款实用的手机移动端图片裁剪插件,支持缩放。
  • 在android调用系统方法对图片进行裁剪时,华为手机显示的图形会变成圆形,改为aspectX和aspectY不是1;1就好 if(android.os.Build.MODEL.contains("HUAWEI")) {//华为特殊处理 不然会显示圆 intent.putExtra(...
  • 手机版 支持旋转和缩放及ajax上传的图片裁剪插件

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 696
精华内容 278
关键字:

手机裁剪图片