前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android CameraUtil 快速集成实现系统相机拍照

Android CameraUtil 快速集成实现系统相机拍照

作者头像
饮水思源为名
发布2019-10-09 15:46:48
1.3K0
发布2019-10-09 15:46:48
举报
文章被收录于专栏:Android小菜鸡Android小菜鸡

   今天又要加打开相机拍照并且上传图片的功能。很多项目都会用到,所以一时兴起,写了个封装类,希望在其他项目中,能够快速引入相机拍照系统。

如何配置:

代码语言:javascript
复制
/*
* 1.首先在AndroidManifest中复制以下代码,加入provider,避免在7.0以上的手机崩溃(因为7.0修改了uri的权
* 限,不在直接提供外部调用)
*/
 <provider
     android:name="android.support.v4.content.FileProvider"
     android:authorities="com.hjl.artisan.fileProvider"
     android:exported="false"
     android:grantUriPermissions="true">
      <meta-data
             android:name="android.support.FILE_PROVIDER_PATHS"
             android:resource="@xml/file_paths" />
 </provider>

/*
*  新建文件res\xml\file_paths.xml,文件内容如下
*/
<paths>
    <!--path:需要临时授权访问的路径(.代表所有路径)-->
    <!--name:就是你给这个访问路径起个名字-->
    <external-path name="external-path" path="CameraPath" />
</paths>

如何使用:

代码语言:javascript
复制
//启动相机
cameraUtil.gotoCaptureRaw(activity)

//相机回调
 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(requestCode==CameraUtil.REQUEST_CODE_CAPTURE_RAW&&resultCode== Activity.RESULT_OK){
            CameraUtil.imageFile?.let {
                cameraUtil.compressImage(it,object:CameraUtil.CallBack{
                    override fun compressImageComplete(imgBitmap: Bitmap,file:File) {
                         //TODO
                    }
                })
            }
        }
    }

CameraUtil源码:

代码语言:javascript
复制
package com.hjl.artisan.app

import android.Manifest
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.support.v4.content.FileProvider
import android.util.Log
import android.widget.Toast
import com.wusy.wusylibrary.util.permissions.PermissionsManager
import com.wusy.wusylibrary.util.permissions.PermissionsResultAction
import java.io.*
import java.text.SimpleDateFormat
import java.util.*
import kotlin.concurrent.thread

class CameraUtil {

    val TAG: String = "CameraUtil"

    //拍照(返回原始图)
    companion object {
        var imageFile: File? = null     //拍照后保存的照片
        var imgUri: Uri? = null         //拍照后保存的照片的uri
        val AUTHORITY = "com.hjl.artisan.fileProvider" //FileProvider的签名(后面会介绍)
        val REQUEST_CODE_CAPTURE_RAW = 6 //startActivityForResult时的请求码
    }

    /**
     * 打开系统相机
     */
    fun gotoCaptureRaw(activity: Activity) {
        imageFile = createImageFile()
        imageFile?.let {
            val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {  //如果是7.0以上,使用FileProvider,否则会报错
                intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                imgUri = FileProvider.getUriForFile(activity, AUTHORITY, it)
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri) //设置拍照后图片保存的位置
            } else {
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(it)) //设置拍照后图片保存的位置
            }
            intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()) //设置图片保存的格式
            intent.resolveActivity(activity.packageManager)?.let {
                if (PermissionsManager.getInstance().hasPermission(activity, Manifest.permission.CAMERA)) {
                    activity.startActivityForResult(intent, REQUEST_CODE_CAPTURE_RAW) //调起系统相机
                } else {
                    Toast.makeText(activity, "打开相机失败,需要获取相机权限", Toast.LENGTH_SHORT).show()
                    PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(activity,
                        arrayOf(Manifest.permission.CAMERA), object : PermissionsResultAction() {
                            override fun onGranted() {
                                activity.startActivityForResult(intent, REQUEST_CODE_CAPTURE_RAW) //调起系统相机
                            }

                            override fun onDenied(permission: String) {

                            }
                        })
                }
            }
        }
    }

    //生成一个文件
    private fun createImageFile(isCrop: Boolean = false): File? {
        return try {
            var rootFile = File(Environment.getExternalStorageDirectory().toString() + File.separator + "CameraPath")
            if (!rootFile.exists())
                rootFile.mkdirs()
            val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
            val fileName = if (isCrop) "IMG_${timeStamp}_CROP.jpg" else "IMG_$timeStamp.jpg"
            File(rootFile.absolutePath + File.separator + fileName)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    //压缩图片并显示
    fun compressImage(file: File, listener: CallBack) {
        thread {
            var temp = System.currentTimeMillis()
            var bitmap = BitmapFactory.decodeFile(file.absolutePath)
            var compressBitmap = BitmapUtils.decodeBitmap(bitmap, 1080, 1080)
            Log.d("TAG", "原始图片大小  ${bitmap.width} * ${bitmap.height}")
            Log.d("TAG", "压缩后图片大小  ${compressBitmap.width} * ${compressBitmap.height}")
            Log.d("TAG", "加载图片耗时 ${System.currentTimeMillis() - temp}")
            listener.compressImageComplete(compressBitmap, file)
        }
    }

    open interface CallBack {
        fun compressImageComplete(imgBitmap: Bitmap, file: File)
    }

    /**
     * 压缩图片(质量压缩)
     * 压缩BitMap至指定大小以内,并且返回File
     * @param bitmap
     */
    fun compressImage(bitmap: Bitmap): File {
        var baos: ByteArrayOutputStream = 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中
            var length = baos.toByteArray().size
        }
        var format: SimpleDateFormat = SimpleDateFormat("yyyyMMddHHmmss")
        var date: Date = Date(System.currentTimeMillis())
        var filename = format.format(date)
        var file: File = File(Environment.getExternalStorageDirectory(), "$filename.png")
        try {
            var fos: FileOutputStream = FileOutputStream(file)
            try {
                fos.write(baos.toByteArray())
                fos.flush()
                fos.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        }
//        recycleBitmap(bitmap)
        return file;
    }

    fun recycleBitmap(bm: Bitmap) {
        if (null != bm && !bm.isRecycled) {
            bm.recycle()
        }
    }
}

End

最近整理了自己的Github Blog,希望各位大大提意见,点个star,谢谢 传送门:WusyBlog

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.10.08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何配置:
  • 如何使用:
  • CameraUtil源码:
  • End
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档