import android.app.Activity
import android.content.ContentResolver
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.res.Resources
import android.graphics.*
import android.graphics.drawable.Drawable
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.support.v4.app.Fragment
import java.io.*
import java.math.BigDecimal
import java.text.SimpleDateFormat
import java.util.*
import android.util.Log
/**
* Created by Administrator on 2018/7/4/004.
*/
object BitmapUtils {
private val timeStampFormat = SimpleDateFormat("yyyy_MM_dd_HH_mm_ss")
private var tempFile: File? = null
private val f = File("/storage/emulated/0/文件名")
/***
* 图片的缩放方法
*
* @param bgimage
* :源图片资源
* @param newWidth
* :缩放后宽度
* @param newHeight
* :缩放后高度
* @return
*/
fun zoomImage(bgimage: Bitmap, newWidth: Double,
newHeight: Double): Bitmap {
// 获取这个图片的宽和高
val width = bgimage.width.toFloat()
val height = bgimage.height.toFloat()
// 创建操作图片用的matrix对象
val matrix = Matrix()
// 计算宽高缩放率
var scaleWidth = newWidth.toFloat() / width
var scaleHeight = newHeight.toFloat() / height
if (scaleWidth > 1)
//如何指定宽度小于本来高度不压缩
scaleWidth = 1f
if (scaleHeight > 1)
scaleHeight = 1f
// 缩放图片动作
matrix.postScale(scaleWidth, scaleHeight)
return Bitmap.createBitmap(bgimage, 0, 0, width.toInt(),
height.toInt(), matrix, true)
}
/**
* 从资源中读取Bitmap
*
* @param res
* @param resId
* @param reqWidth
* @param reqHeight
* @return
*/
fun decodeSampledBitmapFromResource(res: Resources,
resId: Int, reqWidth: Int, reqHeight: Int): Bitmap {
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeResource(res, resId, options)
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight)
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false
return BitmapFactory.decodeResource(res, resId, options)
}
fun saveImage(bmp: Bitmap, context: Context): String? {
val appDir = File(Environment.getExternalStorageDirectory(), "busniss")
if (!appDir.exists()) {
appDir.mkdir()
}
val fileName = System.currentTimeMillis().toString() + ".jpg"
val file = File(appDir, fileName)
try {
val fos = FileOutputStream(file)
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos)
fos.flush()
fos.close()
context.sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE).setData(Uri.fromFile(file)))
return file.path
} catch (e: FileNotFoundException) {
e.printStackTrace()
} catch (e: IOException) {
e.printStackTrace()
}
return null
}
/**
* 解决个别小米
* 相册返回的URI格式和常规不一样的问题
*
* @param intent
* @param activity
* @return
*/
fun parseIntent2Bitmap(intent: Intent?, activity: Activity): Uri {
var uri = intent?.data
val type = intent?.type
if (uri!!.toString() in "com.miui.gallery.open") {
uri = getImageContentUri(activity, File(getRealFilePath(activity, uri)!!))
}
if (uri!!.scheme == "file" && type!!.toString() in "image/") {
var path: String? = uri.encodedPath
if (path != null) {
path = Uri.decode(path)
val cr = activity.contentResolver
val buff = StringBuffer()
buff.append("(").append(MediaStore.Images.ImageColumns.DATA).append("=")
.append("'$path'").append(")")
val cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
arrayOf(MediaStore.Images.ImageColumns._ID),
buff.toString(), null, null)
var index = 0
cur!!.moveToFirst()
while (!cur.isAfterLast) {
index = cur.getColumnIndex(MediaStore.Images.ImageColumns._ID)
// set _id value
index = cur.getInt(index)
cur.moveToNext()
}
if (index == 0) {
// do nothing
} else {
val uri_temp = Uri
.parse("content://media/external/images/media/" + index)
if (uri_temp != null) {
uri = uri_temp
}
}
}
}
return uri
}
fun getImageContentUri(context: Context, imageFile: File): Uri? {
val filePath = imageFile.absolutePath
val cursor = context.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
arrayOf(MediaStore.Images.Media._ID),
MediaStore.Images.Media.DATA + "=? ",
arrayOf(filePath), null)
if (cursor != null && cursor.moveToFirst()) {
val id = cursor.getInt(cursor
.getColumnIndex(MediaStore.MediaColumns._ID))
val baseUri = Uri.parse("content://media/external/images/media")
return Uri.withAppendedPath(baseUri, "" + id)
} else {
if (imageFile.exists()) {
val values = ContentValues()
values.put(MediaStore.Images.Media.DATA, filePath)
return context.contentResolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
} else {
return null
}
}
}
/**
* 从文件中读取Bitmap
*
* @param pathName
* @param reqWidth
* @param reqHeight
* @return
*/
fun decodeSampledBitmapFromFile(pathName: String,
reqWidth: Int, reqHeight: Int): Bitmap? {
var `is`: InputStream? = null
var bm: Bitmap? = null
try {
`is` = FileInputStream(pathName)
// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
options.inPurgeable = true
// BitmapFactory.decodeStream(is, null, options);
BitmapFactory.decodeFile(pathName, options)
// 调用上面定义的方法计算inSampleSize值
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight)
// 使用获取到的inSampleSize值再次解析图片
options.inJustDecodeBounds = false
bm = BitmapFactory.decodeStream(`is`, null, options)
`is`.close()
} catch (e: FileNotFoundException) {
// TODO Auto-generated catch block
e.printStackTrace()
} catch (e: IOException) {
// TODO Auto-generated catch block
e.printStackTrace()
}
return bm
}
// 计算图片的缩放值
private fun calculateInSampleSize(options: BitmapFactory.Options,
reqWidth: Int, reqHeight: Int): Int {
// 源图片的高度和宽度
val height = options.outHeight
val width = options.outWidth
var inSampleSize = 1
if (height > reqHeight || width > reqWidth) {
// 计算出实际宽高和目标宽高的比率
val heightRatio = Math.round(height.toFloat() / reqHeight.toFloat())
val widthRatio = Math.round(width.toFloat() / reqWidth.toFloat())
// 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
// 一定都会大于等于目标的宽和高。
inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio
}
return inSampleSize
}
/**
* 将URI转为图片的路径
*
* @param context
* @param uri
* @return
*/
fun getRealFilePath(context: Context, uri: Uri?): String? {
if (null == uri)
return null
val scheme = uri.scheme
var data: String? = null
if (scheme == null)
data = uri.path
else if (ContentResolver.SCHEME_FILE == scheme) {
data = uri.path
} else if (ContentResolver.SCHEME_CONTENT == scheme) {
val cursor = context.contentResolver.query(uri,
arrayOf(MediaStore.Images.ImageColumns.DATA), null, null, null)
if (null != cursor) {
if (cursor.moveToFirst()) {
val index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
if (index > -1) {
data = cursor.getString(index)
}
}
cursor.close()
}
}
return data
}
fun bitmap2ByteArray(bm: Bitmap): ByteArray {
val baos = ByteArrayOutputStream()
bm.compress(Bitmap.CompressFormat.PNG, 100, baos)
return baos.toByteArray()
}
/**
* 读取图片属性:旋转的角度
*
* @param path 图片绝对路径
* @return degree旋转的角度
*/
fun readPictureDegree(path: String): Int {
var degree = 0
try {
val exifInterface = ExifInterface(path)
val orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL)
when (orientation) {
ExifInterface.ORIENTATION_ROTATE_90 -> degree = 90
ExifInterface.ORIENTATION_ROTATE_180 -> degree = 180
ExifInterface.ORIENTATION_ROTATE_270 -> degree = 270
}
} catch (e: IOException) {
e.printStackTrace()
}
return degree
}
/**
* 旋转图片
*
* @param angle
* @param bitmap
* @return Bitmap
*/
fun rotaingImageView(angle: Int, bitmap: Bitmap): Bitmap {
// 旋转图片 动作
val matrix = Matrix()
matrix.postRotate(angle.toFloat())
Log.e("msg", "angle2=" + angle)
// 创建新的图片
return Bitmap.createBitmap(bitmap, 0, 0,
bitmap.width, bitmap.height, matrix, true)
}
/**
* 保存图片
*
* @return Bitmap
*/
fun saveMyBitmap(filePath: String, mBitmap: Bitmap) {
val f = File(filePath)
var fOut: FileOutputStream? = null
try {
fOut = FileOutputStream(f)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut)
try {
fOut!!.flush()
} catch (e: IOException) {
e.printStackTrace()
}
try {
fOut!!.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
/**
* 判断SD卡上的文件夹是否存在
*/
fun isFileExist(fileName: String): Boolean {
try {
val file = File(fileName)
return file.exists()
} catch (e: Exception) {
return false
}
}
private fun neoUri(context: Context): Uri {
val f = File(context.externalCacheDir, "${System.currentTimeMillis()}.jpg")
try {
if (f.exists()) {
f.delete()
}
f.createNewFile()
} catch (e: IOException) {
e.printStackTrace()
}
return Uri.fromFile(f)
}
fun cropPortrait(activity: Activity?, fragment: Fragment?, uri: Uri?, REQUEST_CODE: Int): Uri {
val output = if (activity != null) neoUri(activity) else fragment?.context?.let { neoUri(it) }
val intent = Intent("com.android.camera.action.CROP")
intent.setDataAndType(uri, "image/*")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
//设置裁剪
intent.putExtra("crop", true)
//这里是针对华为的,华为裁剪的时候显示是圆的,这个就不是圆的了
if (Build.MANUFACTURER == "HUAWEI") {
intent.putExtra("aspectX", 9998)
intent.putExtra("aspectY", 9999)
} else {
//比例
intent.putExtra("aspectX", 1)
intent.putExtra("aspectY", 1)
}
//裁剪宽高
intent.putExtra("scale", true)//黑边
intent.putExtra("scaleUpIfNeeded", true)//黑边
intent.putExtra("outputX", 300)
intent.putExtra("outputY", 300)
intent.putExtra("return-data", false)
intent.putExtra(MediaStore.EXTRA_OUTPUT, output)
activity?.startActivityForResult(intent, REQUEST_CODE)
fragment?.startActivityForResult(intent, REQUEST_CODE)
return output!!
}
/**
* 获得bitmap的大小(kb)
*
* @param bitmap
* @return
*/
fun getBitmapSize(bitmap: Bitmap): Int {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //API 19
return bitmap.allocationByteCount / 1024
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {//API 12
bitmap.byteCount / 1024
} else bitmap.rowBytes * bitmap.height / 1024
// 在低版本中用一行的字节x高度
//earlier version
}
fun openCamera70(activity: Activity, requestCode: Int): Uri? {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
val filename = timeStampFormat.format(Date())
if (!f.exists()) f.mkdirs()
tempFile = File(f, filename + ".jpg")
//兼容android7.0 使用共享文件的形式
val contentValues = ContentValues(1)
contentValues.put(MediaStore.Images.Media.DATA, tempFile!!.absolutePath)
val uri = activity.applicationContext.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
activity.startActivityForResult(intent, requestCode)
return uri
}
/**
* bitmap图片压缩
*/
fun reduce(bitmap: Bitmap, width: Int, height: Int, isAdjust: Boolean): Bitmap {
if (bitmap.width < width && bitmap.height < height) {
return bitmap
}
var sx = BigDecimal(width).divide(BigDecimal(bitmap.width), 4, BigDecimal.ROUND_DOWN).toFloat()
var sy = BigDecimal(height).divide(BigDecimal(bitmap.height), 4, BigDecimal.ROUND_DOWN).toFloat()
if (isAdjust) {
sx = if (sx < sy) sx else sy
sy = sx
}
val matrix = Matrix()
matrix.postScale(sx, sy)
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
fun compressImage(image: Bitmap?, sizeKb: Int): Bitmap {
val baos = ByteArrayOutputStream()
image?.compress(Bitmap.CompressFormat.PNG, 100, baos)
var options = 90
while (baos.toByteArray().size / 1024 > sizeKb) {
baos.reset() // 重置baos即清空baos
image?.compress(Bitmap.CompressFormat.PNG, options, baos)
options -= 10// 每次都减少10
}
val isBm = ByteArrayInputStream(baos.toByteArray())
return BitmapFactory.decodeStream(isBm, null, null)
}
fun uri2bitmap(uri: Uri?, activity: Activity): Bitmap? {
var bitmap: Bitmap? = null
try {
bitmap = MediaStore.Images.Media.getBitmap(activity.contentResolver, uri)
} catch (e: IOException) {
e.printStackTrace()
}
return bitmap
}
fun bitmap2uri(bitmap: Bitmap?, context: Context): Uri? {
return if (bitmap == null) null else Uri.parse(MediaStore.Images.Media.insertImage(context.contentResolver, bitmap, null, null))
}
fun cropPhoto4(activity: Activity, uri: Uri, REQUEST_CODE: Int) {
val intent = Intent("com.android.camera.action.CROP")
intent.setDataAndType(uri, "image/*")
//设置裁剪
intent.putExtra("crop", true)
//比例
intent.putExtra("aspectX", 5)
intent.putExtra("aspectY", 5)
//裁剪宽高
intent.putExtra("scale", true)//黑边
intent.putExtra("scaleUpIfNeeded", true)//黑边
intent.putExtra("outputX", 2000)
intent.putExtra("outputY", 2000)
intent.putExtra("return-data", false)
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
activity.startActivityForResult(intent, REQUEST_CODE)
}
fun getBitmap(drawable: Drawable): Bitmap {
val bitmap = Bitmap.createBitmap(
drawable.intrinsicWidth,
drawable.intrinsicHeight,
if (drawable.opacity != PixelFormat.OPAQUE) Bitmap.Config.ARGB_8888 else Bitmap.Config.RGB_565)
val canvas = Canvas(bitmap)
//canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
drawable.draw(canvas)
return bitmap
}
}