package com.convenient.android.common.utils.image

import android.R
import android.annotation.SuppressLint
import android.content.Context
import android.content.res.ColorStateList
import android.content.res.Resources
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.StateListDrawable
import android.media.ExifInterface
import android.net.Uri
import android.os.Build
import android.view.View
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.AppCompatImageButton
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat
import com.convenient.android.common.extension.getDensity
import com.convenient.android.common.extension.toFile
import com.convenient.android.common.utils.file.CloseUtils
import com.convenient.android.common.utils.file.FileIOUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.*


/**
 * @classname：BitmapUtils
 * @author：wangzhe
 * @date：2018/9/13 下午2:19
 * @description：
 */
object BitmapUtils {


    /**
     * 从资源中解码经过采样处理后的bitmap
     */
    fun decodeSampledBitmapFromResource(res: Resources?, @DrawableRes 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 decodeSampledBitmapFromPath(path: String?, reqWidth: Int, reqHeight: Int): Bitmap? {
        // 第一次解析将inJustDecodeBounds设置为true，来获取图片大小
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        BitmapFactory.decodeFile(path, options)
        // 调用上面定义的方法计算inSampleSize值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
        // 使用获取到的inSampleSize值再次解析图片
        options.inJustDecodeBounds = false
        return BitmapFactory.decodeFile(path, options)
    }


    /**
     * 从uri中解码经过采样的图片
     */
    fun decodeSampledBitmapFromUri(context: Context?, uri: Uri?, reqWidth: Int, reqHeight: Int): Bitmap? {
        if (context == null || uri == null) return null
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        val fileDescriptor = context.contentResolver.openFileDescriptor(uri, "r") ?: return null
        BitmapFactory.decodeFileDescriptor(fileDescriptor.fileDescriptor, null, options)
        fileDescriptor.close()
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
        options.inJustDecodeBounds = false
        val f = context.contentResolver.openFileDescriptor(uri, "r")
        val bitmap = BitmapFactory.decodeFileDescriptor(f?.fileDescriptor)
        f?.close()
        return bitmap
    }


    fun getBitmapByResource(context: Context?, @DrawableRes resId: Int): Bitmap? {
        val drawable = ContextCompat.getDrawable(context!!, resId)
        val bd = drawable as BitmapDrawable?
        return bd!!.bitmap
    }


    /**
     * 计算图片的采样大小
     */
    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
    }


    /**
     * @param image
     * @param percent 压缩百分比
     * @return
     * @方法说明:质量压缩方法
     * @方法名称:compressImage
     * @返回值:Bitmap
     */
    fun compressImage(image: Bitmap, percent: Int): Bitmap? {
        val baos = ByteArrayOutputStream()
        image.compress(Bitmap.CompressFormat.JPEG, percent, baos) // 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        var options = 60
        while (baos.toByteArray().size / 1024 > 80) { // 循环判断如果压缩后图片是否大于80kb,大于继续压缩
            baos.reset() // 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos) // 这里压缩options%，把压缩后的数据存放到baos中
            options -= 10 // 每次都减少10
        }
        val isBm = ByteArrayInputStream(baos.toByteArray()) // 把压缩后的数据baos存放到ByteArrayInputStream中
        return BitmapFactory.decodeStream(isBm, null, null)
    }


    /**
     * 从文件获取bitmap
     */
    fun getBitmapFromFile(filePath: String?): Bitmap? = getBitmapFromFilePath(filePath?.toFile())


    fun getBitmapFromFilePath(file: File?): Bitmap? {
        return try {
            if (file == null) return null
            if (file.exists().not()) return null
            val opts = BitmapFactory.Options()
            opts.inJustDecodeBounds = false
            opts.inSampleSize = 1
            opts.inPreferredConfig = Bitmap.Config.RGB_565
            BitmapFactory.decodeFile(file.absolutePath, opts)
        } catch (e: Exception) {
            null
        }
    }

    /**
     * 保存bitmap到文件
     * @param bitmap 需要保存的bitmap
     * @param file 要存储到的文件位置
     * @param quality 保存的图片质量
     * @param compressFormat 保存的格式
     */
    fun saveBitmapToFile(bitmap: Bitmap?, file: File?, quality: Int = 100, compressFormat: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG): Boolean {
        bitmap ?: return false
        file ?: return false

        if (bitmap.isRecycled) return false

        if (!file.exists()) file.createNewFile()

        return try {
            file.outputStream()
                .use {
                    bitmap.compress(compressFormat, quality, it)
                    it.flush()
                    true
                }
        } catch (e: Exception) {
            //基本出现这里就异常的是File 文件区域没有读写权限导致的。
            return false
        }
    }

    /**
     * 保存bitmap到文件， 文件名称为 yyyyMMddHHmmss.compressFormat
     * @param bitmap 要保存的bitmap
     * @param dir 要保存的目标目录
     * @param compressFormat 保存的格式
     */
    @SuppressLint("SimpleDateFormat")
    fun saveBitmapToFile(bitmap: Bitmap?, dir: String, compressFormat: Bitmap.CompressFormat = Bitmap.CompressFormat.PNG): String? {
        val tempType = compressFormat.name.lowercase()
        val file = File(dir, "${SimpleDateFormat("yyyyMMddHHmmss").format(Date(System.currentTimeMillis()))}.$tempType")
        return saveBitmapToFile(bitmap = bitmap, file = file, compressFormat = compressFormat).run {
            when {
                this -> file.canonicalPath
                else -> null
            }
        }
    }


    /**
     * @methodName：rotateImage created by liujiyuan on 2019-12-03 18:30.
     * @description：把图片顺时针旋转
     */
    fun rotateImage(bitmap: Bitmap?, degrees: Float): Bitmap? {
        return try {
            if (degrees == 0f || null == bitmap) {
                return bitmap
            }
            val matrix = Matrix().apply {
                setRotate(degrees)
            }

            val bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
            bitmap.recycle()
            bmp
        } catch (e: Exception) {
            null
        }
    }

    /**
     * 读取图片的旋转的角度
     *
     * @param path 图片绝对路径
     * @return 图片的逆时针旋转角度
     */
    fun getBitmapDegree(path: String?): Int {
        if (path.isNullOrEmpty()) {
            return 0
        }
        return try { // 从指定路径下读取图片，并获取其EXIF信息
            val exifInterface = ExifInterface(path)
            // 获取图片的旋转信息
            val orientation = exifInterface.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL
            )
            when (orientation) {
                ExifInterface.ORIENTATION_ROTATE_90 -> 90
                ExifInterface.ORIENTATION_ROTATE_180 -> 180
                ExifInterface.ORIENTATION_ROTATE_270 -> 270
                else -> 0
            }
        } catch (e: Exception) {
            0
        }
    }

    @RequiresApi(Build.VERSION_CODES.N)
    fun getBitmapDegree(input: InputStream?): Int {
        if (input == null) {
            return 0
        }
        return try { // 从指定路径下读取图片，并获取其EXIF信息
            val exifInterface = ExifInterface(input)
            // 获取图片的旋转信息
            val orientation = exifInterface.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL
            )
            when (orientation) {
                ExifInterface.ORIENTATION_ROTATE_90 -> 90
                ExifInterface.ORIENTATION_ROTATE_180 -> 180
                ExifInterface.ORIENTATION_ROTATE_270 -> 270
                else -> 0
            }
        } catch (e: Exception) {
            0
        }
    }


    /**
     * @methodName：rotatePicture created by liujiyuan on 2019-12-03 18:06.
     * @description：把图片的旋转角度变为0，使图片不是颠倒的
     */
    suspend fun rotatePicture(path: String?): Boolean {
        return withContext(Dispatchers.IO) {
            val degree = getBitmapDegree(path)
            if (degree > 0){
                val bitmap = getBitmapFromFile(path)
                bitmap?.let {
                    try {
                        rotateImage(it, degree.toFloat()).run {
                            saveBitmapToFile(bitmap, path?.toFile())
                        }
                    }catch (e : Exception){
                        false
                    } finally {
                        bitmap.apply { if (!isRecycled) recycle() }
                    }
                }?:false
            }else{
                true
            }
        }
    }

    /**
     * @methodName： created by liujiyuan on 2020/7/23 下午2:01.
     * @description：通过uri把bitmap保存到指定路径
     */
    // TODO: 待测试
    fun saveBitmapFromUri(context: Context, uri: Uri, path: String?) {
        FileIOUtils.writeFileFromIS(path?.toFile(), context.contentResolver.openInputStream(uri))
    }


    /**
     * 替换bitmap 指定颜色
     * @param srcColor 源颜色
     * @param destColor 替换后的颜色
     */
    fun replaceBitmapColor(bitmap: Bitmap?, srcColor : Int, destColor : Int): Bitmap? {
        bitmap?.apply {
            if (isRecycled) {
                return null
            }
            val picw = width
            val pich = height
            val pix = IntArray(picw * pich)
            getPixels(pix, 0, picw, 0, 0, picw, pich)
            for (y in 0 until pich) {
                for (x in 0 until picw) {
                    val index = y * picw + x
                    if (pix[index] == srcColor) {
                        pix[index] = destColor
                    }
                }
            }
            recycle()
            return Bitmap.createBitmap(pix, picw, pich, Bitmap.Config.ARGB_8888)
        }
        return null
    }

    /**
     * @methodName： created by liujiyuan on 2020/11/3 上午9:13.
     * @description：压缩图片
     */
    fun compressImageForSize(image: Bitmap?, size: Int): Bitmap? {
        if (image == null || image.isRecycled) {
            return null
        }
        synchronized(image) {
            val baos = ByteArrayOutputStream()
            // 质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
            image.compress(Bitmap.CompressFormat.PNG, 100, baos)
            var options = 100
            val len: Int = baos.toByteArray().size / 1024
            if (len > size) {
                options = options * size / len
                if (options == 0) {
                    options = 1
                }
            }
            baos.reset() // 重置baos即清空baos
            // 这里压缩options%，把压缩后的数据存放到baos中
            image.compress(Bitmap.CompressFormat.PNG, options, baos)
            // 把压缩后的数据baos存放到ByteArrayInputStream中
            val isBm = ByteArrayInputStream(baos.toByteArray())
            // 把ByteArrayInputStream数据生成图片
            val bitmap = BitmapFactory.decodeStream(isBm, null, null)
            CloseUtils.closeIO(baos, isBm)
            if (!image.isRecycled) {
                image.recycle()
            }
            return bitmap
        }
    }


    /**
     * @methodName： created by liujiyuan on 2020/11/3 上午9:16.
     * @description：裁剪bitmap
     */
    @JvmStatic
    fun createBitmapFitRect(temp: Bitmap?, width: Float, height: Float): Bitmap? {
        if (temp == null || temp.isRecycled || width <= 0 || height <= 0) {
            return null
        }
        val imageHeight = temp.height
        val imageWidth = temp.width
        //String imageType = options.outMimeType;
        val radio: Float = when {
            imageHeight / height > imageWidth / width -> height / imageHeight
            else -> width / imageWidth
        }
        val matrix = Matrix()
        matrix.preScale(radio, radio)
        return Bitmap.createBitmap(temp, 0, 0, imageWidth, imageHeight, matrix, true)
    }


    fun fitBitmap(target: Bitmap?, newWidth: Int, isRecycle: Boolean): Bitmap? {
        var bmp: Bitmap? = null
        target?.run {
            val width = width
            val height = height
            val matrix = Matrix()
            val scaleWidth = newWidth.toFloat() / width
            matrix.postScale(scaleWidth, scaleWidth)
            bmp = Bitmap.createBitmap(
                this, 0, 0, width, height, matrix,
                true
            )
            if (isRecycle) if (this != bmp && !isRecycled) recycle()
        }
        return bmp
    }


    /**
     * 缩放图片
     */
    fun scaleImage(bitmap: Bitmap?, width: Int): Bitmap? {
        if (bitmap == null) {
            return null
        }
        val scale = (width * 1F) / bitmap.width
        if (scale > 1) {
            return bitmap
        }
        return scaleImage(bitmap, scale, scale)

    }

    /**
     * 图片缩放
     *
     * @param bitmap
     * @param sx
     * @param sy
     * @return
     */
    fun scaleImage(bitmap: Bitmap?, sx: Float, sy: Float): Bitmap? {
        if (bitmap == null) {
            return null
        }
        val matrix = Matrix()
        matrix.setScale(sx, sy)
        return Bitmap.createBitmap(
            bitmap, 0, 0, bitmap.width,
            bitmap.height, matrix, false
        )
    }


    fun rotateImageCanvas(bm: Bitmap, orientationDegree: Int): Bitmap? {
        val m = Matrix()
        m.setRotate(orientationDegree.toFloat(), bm.width.toFloat() / 2, bm.height.toFloat() / 2)
        val targetX: Float
        val targetY: Float
        if (orientationDegree == 90) {
            targetX = bm.height.toFloat()
            targetY = 0f
        } else {
            targetX = bm.height.toFloat()
            targetY = bm.width.toFloat()
        }
        val values = FloatArray(9)
        m.getValues(values)
        val x1 = values[Matrix.MTRANS_X]
        val y1 = values[Matrix.MTRANS_Y]
        m.postTranslate(targetX - x1, targetY - y1)
        val bm1 = Bitmap.createBitmap(bm.height, bm.width, Bitmap.Config.ARGB_8888)
        val paint = Paint()
        val canvas = Canvas(bm1)
        canvas.drawBitmap(bm, m, paint)
        return bm1
    }

    /**
     * 获取圆形图片
     *
     * @param bitmap
     * @param length 返回图片的宽高
     * @param l      图片粘贴的左上角位置
     * @param t
     * @return
     */
    fun getRoundedCornerBitmap(context: Context?, bitmap: Bitmap?, length: Int, l: Int, t: Int): Bitmap? {
        if (bitmap == null) {
            return null
        }
        val output = Bitmap.createBitmap(length, length, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(output)
        val color = -0x1000000
        val paint = Paint()
        val rect = Rect(0, 0, length, length)
        val rectF = RectF(rect)
        val roundPx = length * 0.5f
        paint.isAntiAlias = true
        canvas.drawARGB(0, 0, 0, 0)
        paint.color = color
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint)
        paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        canvas.drawBitmap(bitmap, l.toFloat(), t.toFloat(), paint)
        paint.color = Color.GREEN
        val len = 10
        canvas.drawLine((length / 2 - len).toFloat(), (length / 2).toFloat(), (length / 2 + len).toFloat(), (length / 2).toFloat(), paint)
        canvas.drawLine((length / 2).toFloat(), (length / 2 - len).toFloat(), (length / 2).toFloat(), (length / 2 + len).toFloat(), paint)
        paint.strokeWidth = 2 * context.getDensity()
        paint.color = Color.WHITE
        paint.style = Paint.Style.STROKE
        canvas.drawCircle((length / 2).toFloat(), (length / 2).toFloat(), length / 2 - 1 * context.getDensity(), paint)
        return output
    }


    /**
     * 图片灰度处理
     *
     * @param bitmap
     * @return
     */
    fun greyscale(bitmap: Bitmap?): Bitmap? {
        if (bitmap == null) {
            return null
        }
        val colorMatrix = ColorMatrix()
        colorMatrix.setSaturation(0f)
        val width = bitmap.width
        val height = bitmap.height
        val buffer: Bitmap
        try {
            buffer = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
            val canvas = Canvas(buffer)
            val paint = Paint()
            paint.colorFilter = ColorMatrixColorFilter(colorMatrix)
            canvas.drawBitmap(bitmap, 0f, 0f, paint)
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            return bitmap
        }
        return buffer
    }


    /**
     * 图片透明度处理
     *
     * @param bitmap 原始图片
     * @param alpha  透明度
     * @return
     */
    fun setAlpha(bitmap: Bitmap?, alpha: Int): Bitmap? {
        if (bitmap == null) {
            return null
        }
        val argb = IntArray(bitmap.width * bitmap.height)
        bitmap.getPixels(
            argb, 0, bitmap.width, 0, 0, bitmap.width,
            bitmap.height
        ) // 获得图片的ARGB值
        var al: Int
        for (i in argb.indices) {
            al = (Color.alpha(argb[i]) * alpha / 100f).toInt()
            argb[i] = al shl 24 or (argb[i] and 0x00FFFFFF) // 修改最高2位的值
        }
        return Bitmap.createBitmap(
            argb, bitmap.width,
            bitmap.height, Bitmap.Config.ARGB_8888
        )
    }


    /**
     * 图片进行亮度和对比度的处理
     *
     * @param src
     * @param light
     * @param contrast
     * @return
     */
    fun filter(src: Bitmap?, light: Int, contrast: Int): Bitmap? {
        if (src == null) {
            return null
        }
        return if (light == -1 && contrast == -1) { //默认值
            src
        } else {
            val width = src.width
            val height = src.height
            val b = light / 50f
            val c = (contrast + 20) / 40f
            val inPixels: IntArray
            val outPixels: IntArray
            try {
                inPixels = IntArray(width * height)
                outPixels = IntArray(width * height)
            } catch (e: OutOfMemoryError) {
                e.printStackTrace()
                return src
            }
            src.getPixels(inPixels, 0, width, 0, 0, width, height)

            // calculate RED, GREEN, BLUE means of pixel
            var index = 0
            val rgbmeans = IntArray(3)
            var redSum = 0.0
            var greenSum = 0.0
            var blueSum = 0.0
            val total = (height * width).toDouble()
            for (row in 0 until height) {
                // int ta = 0;
                var tr = 0
                var tg = 0
                var tb = 0
                for (col in 0 until width) {
                    index = row * width + col
                    // ta = (inPixels[index] >> 24) & 0xff;
                    tr = inPixels[index] shr 16 and 0xff
                    tg = inPixels[index] shr 8 and 0xff
                    tb = inPixels[index] and 0xff
                    redSum += tr.toDouble()
                    greenSum += tg.toDouble()
                    blueSum += tb.toDouble()
                }
            }
            rgbmeans[0] = (redSum / total).toInt()
            rgbmeans[1] = (greenSum / total).toInt()
            rgbmeans[2] = (blueSum / total).toInt()

            // adjust contrast and brightness algorithm, here
            for (row in 0 until height) {
                var ta = 0
                var tr = 0
                var tg = 0
                var tb = 0
                for (col in 0 until width) {
                    index = row * width + col
                    ta = inPixels[index] shr 24 and 0xff
                    tr = inPixels[index] shr 16 and 0xff
                    tg = inPixels[index] shr 8 and 0xff
                    tb = inPixels[index] and 0xff

                    // remove means
                    tr -= rgbmeans[0]
                    tg -= rgbmeans[1]
                    tb -= rgbmeans[2]

                    // adjust contrast now !!!
                    tr = (tr * c).toInt()
                    tg = (tg * c).toInt()
                    tb = (tb * c).toInt()

                    // adjust brightness
                    tr += (rgbmeans[0] * b).toInt()
                    tg += (rgbmeans[1] * b).toInt()
                    tb += (rgbmeans[2] * b).toInt()
                    outPixels[index] = (ta shl 24 or (clamp(tr) shl 16)
                            or (clamp(tg) shl 8) or clamp(tb))
                }
            }
            val dest: Bitmap
            dest = try {
                Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
            } catch (e: OutOfMemoryError) {
                // TODO Auto-generated catch block
                e.printStackTrace()
                return null
            }
            dest.setPixels(outPixels, 0, width, 0, 0, width, height)
            dest
        }
    }

    fun clamp(value: Int): Int {
        return if (value > 255) 255 else if (value < 0) 0 else value
    }


    /**
     * 二值化处理
     *
     * @param img
     * @return
     */
    fun binarization(img: Bitmap?): Bitmap? {
        if (img == null) {
            return null
        }
        val width = img.width
        val height = img.height
        val area = width * height
        val gray = Array(width) { IntArray(height) }
        var average = 0 // 灰度平均值
        var graysum = 0
        var graymean = 0
        var grayfrontmean = 0
        var graybackmean = 0
        var pixelGray: Int
        var front = 0
        var back = 0
        val pix = IntArray(width * height)
        img.getPixels(pix, 0, width, 0, 0, width, height)
        for (i in 1 until width) { // 不算边界行和列，为避免越界
            for (j in 1 until height) {
                val x = j * width + i
                val r = pix[x] shr 16 and 0xff
                val g = pix[x] shr 8 and 0xff
                val b = pix[x] and 0xff
                pixelGray = (0.3 * r + 0.59 * g + 0.11 * b).toInt() // 计算每个坐标点的灰度
                gray[i][j] = (pixelGray shl 16) + (pixelGray shl 8) + pixelGray
                graysum += pixelGray
            }
        }
        graymean = graysum / area // 整个图的灰度平均值
        average = graymean
        for (i in 0 until width) { // 计算整个图的二值化阈值
            for (j in 0 until height) {
                if (gray[i][j] and 0x0000ff < graymean) {
                    graybackmean += gray[i][j] and 0x0000ff
                    back++
                } else {
                    grayfrontmean += gray[i][j] and 0x0000ff
                    front++
                }
            }
        }
        var frontvalue = 0
        var backvalue = 0
        if (front <= 0 || back <= 0) {
            return img
        }
        frontvalue = grayfrontmean / front // 前景中心
        backvalue = graybackmean / back // 背景中心
        val G = FloatArray(frontvalue - backvalue + 1) // 方差数组
        var s = 0
        for (i1 in backvalue until frontvalue + 1)  // 以前景中心和背景中心为区间采用大津法算法（OTSU算法）
        {
            back = 0
            front = 0
            grayfrontmean = 0
            graybackmean = 0
            for (i in 0 until width) {
                for (j in 0 until height) {
                    if (gray[i][j] and 0x0000ff < i1 + 1) {
                        graybackmean += gray[i][j] and 0x0000ff
                        back++
                    } else {
                        grayfrontmean += gray[i][j] and 0x0000ff
                        front++
                    }
                }
            }
            if (front <= 0 || back <= 0) {
                return img
            }
            grayfrontmean = grayfrontmean / front
            graybackmean = graybackmean / back
            G[s] = (back.toFloat() / area * (graybackmean - average)
                    * (graybackmean - average)) + (front.toFloat() / area
                    * (grayfrontmean - average) * (grayfrontmean - average))
            s++
        }
        var max = G[0]
        var index = 0
        for (i in 1 until frontvalue - backvalue + 1) {
            if (max < G[i]) {
                max = G[i]
                index = i
            }
        }
        for (i in 0 until width) {
            for (j in 0 until height) {
                val `in` = j * width + i
                if (gray[i][j] and 0x0000ff < index + backvalue) {
                    pix[`in`] = Color.rgb(0, 0, 0)
                } else {
                    pix[`in`] = Color.rgb(255, 255, 255)
                }
            }
        }
        val temp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)
        temp.setPixels(pix, 0, width, 0, 0, width, height)
        return temp
    }

    fun getTintDrawableList(context: Context?, srcResourceId: Int, colorResId: Int, colorPressedResId: Int): Drawable? {
        var drawable = ContextCompat.getDrawable(context!!, srcResourceId)
        val colors = intArrayOf(
            ContextCompat.getColor(context, colorPressedResId),
            ContextCompat.getColor(context, colorPressedResId),
            ContextCompat.getColor(context, colorResId)
        )
        val states = arrayOfNulls<IntArray>(3)
        states[0] = intArrayOf(R.attr.state_pressed)
        states[1] = intArrayOf(R.attr.state_selected)
        states[2] = intArrayOf()
        val colorList = ColorStateList(states, colors)
        val stateListDrawable = StateListDrawable()
        stateListDrawable.addState(states[0], drawable) //注意顺序
        stateListDrawable.addState(states[1], drawable)
        stateListDrawable.addState(states[2], drawable)
        val state = stateListDrawable.constantState
        drawable = DrawableCompat.wrap(state?.newDrawable() ?: stateListDrawable).mutate()
        DrawableCompat.setTintList(drawable, colorList)
        drawable.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)
        return drawable
    }

    /**
     * @param:
     * @author: luozhipeng
     * @Decreption:通过tint实现图片selector
     * @create at: 8/8/16 16:17
     */
    fun setTintDrawableList(context: Context?, view: View?, srcResourceId: Int, colorResId: Int, colorPressedResId: Int) {
        var drawable = ContextCompat.getDrawable(context!!, srcResourceId)
        val colors = intArrayOf(
            ContextCompat.getColor(context, colorPressedResId),
            ContextCompat.getColor(context, colorPressedResId),
            ContextCompat.getColor(context, colorResId)
        )
        val states = arrayOfNulls<IntArray>(3)
        states[0] = intArrayOf(R.attr.state_pressed)
        states[1] = intArrayOf(R.attr.state_selected)
        states[2] = intArrayOf()
        val colorList = ColorStateList(states, colors)
        val stateListDrawable = StateListDrawable()
        stateListDrawable.addState(states[0], drawable) //注意顺序
        stateListDrawable.addState(states[1], drawable)
        stateListDrawable.addState(states[2], drawable)
        val state = stateListDrawable.constantState
        drawable = DrawableCompat.wrap(state?.newDrawable() ?: stateListDrawable).mutate()
        DrawableCompat.setTintList(drawable, colorList)
        drawable.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)
        if (view is AppCompatImageView) {
            view.setImageDrawable(drawable)
        }
        if (view is ImageView) {
            view.setImageDrawable(drawable)
        }
        if (view is AppCompatImageButton) {
            view.setImageDrawable(drawable)
        }
    }


    /**
     * bitmap文件是否可用
     */
    fun bitmapFileIsAvailable(bitmapFilePath: String): Boolean {
        return try {
            val options = BitmapFactory.Options()
            options.inJustDecodeBounds = false
            val bitmap = BitmapFactory.decodeFile(bitmapFilePath, options)
            bitmap != null
        } catch (e: Exception) {
            false
        }
    }

}