bitmap封装大全



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
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值