GitHub链接
https://github.com/soulListener/ViewPratice/tree/master/kpicturepick
1.选择图片
Intent i = new Intent( Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, RESULT_LOAD_IMAGE);
2.拍照并切割
takephoto.setOnClickListener{
//获取系统版本
val currentapiVersion = android.os.Build.VERSION.SDK_INT
//激活相机
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
//判断存储卡是否可用 可用进行存储
if (hasSdcard()){
val simpleDateFormat = SimpleDateFormat("yyyy_MM_dd_mm_ss")
val fileName = simpleDateFormat.format(Date())
val tempFile = File(Environment.getExternalStorageDirectory(),fileName+".jpg")
if (currentapiVersion<24){
//从文件中创建uri
imageUri = Uri.fromFile(tempFile)
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)
}else{
//兼容android7.0 使用共享文件的形式
val contentValues = ContentValues(1)
contentValues.put(MediaStore.Images.Media.DATA, tempFile.absolutePath)
//检查是否有存储权限,以免崩溃
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//申请WRITE_EXTERNAL_STORAGE权限
ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),0)
Toast.makeText(this,"请开启存储权限", Toast.LENGTH_SHORT).show()
}
imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)
}
}
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA
startActivityForResult(intent,RESULT_TAKE_PHOTO);
}
3.返回回调
@SuppressLint("NewApi")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode ){
RESULT_LOAD_IMAGE ->{
val slesctedImage = data!!.data
val filePathColumn =arrayOf(MediaStore.Images.Media.DATA)
val cursor =contentResolver.query(slesctedImage,
filePathColumn,null,null,null)
cursor.moveToFirst()
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()
imageview.background = Drawable.createFromPath(picturePath)
}
RESULT_TAKE_PHOTO ->{
Log.e("TAG","RESULT_TAKE_PHOTO")
val imageUri =imageUri
val intent = Intent("com.android.camera.action.CROP")
intent.setDataAndType(imageUri,"image/*")
intent.putExtra("scale",true)
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)
//启动裁剪程序
startActivityForResult(intent,RESULT_CROP_PHOTO)
}
RESULT_CROP_PHOTO ->{
Log.e("TAG","RESULT_CROP_PHOTO")
val imageUri =imageUri
val bitmap = BitmapFactory.decodeStream(contentResolver.openInputStream(imageUri))
imageview.setImageBitmap(bitmap)
}
else ->{
Log.e("TAG","123")
}
}
}
获取ImageView图片
第一种
//开启图片缓存
iv_show.isDrawingCacheEnabled = true
//获取图片缓存
baseBitmap = iv_show.getDrawingCache()
//关闭图片缓存
iv_show.isDrawingCacheEnabled = false
第二种
baseBitmap= (iv_show .drawable as BitmapDrawable).bitmap
遇到的问题:
1.Immutable bitmap passed to Canvas constructor 异常
异常原因:
发生这个异常是由于android不允许直接对drawable目录中的图片进行修改的,而直接通过该函数创建出来的Bitmap对象,具有直接修改图片资源的能力。只能通过拷贝一个id参数所对应图片资源的副本来创建Bitmap。
解决方法:
Android api中还是考虑到了这种情况的,只需要将原drawable拷贝出一个副本,使用这个副本就行了。
2.选择图片的时候可能会出现图片占用内存过大导致OOM
此时要进行图片压缩
val options = BitmapFactory.Options()
//只获取图片的大小信息 而不是将整张图片载入内存中 避免内存溢出
options.inJustDecodeBounds =true
BitmapFactory.decodeFile(picturePath,options)
val height = options.outHeight
val width = options.outWidth
var inSampleSize =2//默认像素压缩比例 压缩为原图的1/2
val minLen = Math.min(height,width)//原图的最小边长
if (minLen >100){
//如果㡳图像的最小边长大于100dp()
val ratio = minLen /100.0f //计算像素压缩比例
inSampleSize = ratio.toInt()
}
options.inJustDecodeBounds =false //计算好压缩比例后 加载原图
options.inSampleSize = inSampleSize//设置为刚才计算的压缩比例
val bm = BitmapFactory.decodeFile(picturePath,options)//解码文件
iv_show.scaleType = ImageView.ScaleType.FIT_CENTER
iv_show.setImageBitmap(bm)