diff --git a/imagepicker/build.gradle b/imagepicker/build.gradle index 39aa0d0d..a416e620 100644 --- a/imagepicker/build.gradle +++ b/imagepicker/build.gradle @@ -50,6 +50,7 @@ dependencies { //More Info: https://github.com/Yalantis/uCrop implementation 'com.github.yalantis:ucrop:2.2.6' + implementation "com.github.forJrking:KLuban:1.1.0" testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.2' diff --git a/imagepicker/src/main/kotlin/com/github/dhaval2404/imagepicker/provider/CompressionProvider.kt b/imagepicker/src/main/kotlin/com/github/dhaval2404/imagepicker/provider/CompressionProvider.kt index 9555b73c..d5ee3044 100644 --- a/imagepicker/src/main/kotlin/com/github/dhaval2404/imagepicker/provider/CompressionProvider.kt +++ b/imagepicker/src/main/kotlin/com/github/dhaval2404/imagepicker/provider/CompressionProvider.kt @@ -1,15 +1,12 @@ package com.github.dhaval2404.imagepicker.provider import android.annotation.SuppressLint -import android.graphics.Bitmap import android.net.Uri -import android.os.AsyncTask import android.os.Bundle +import com.forjrking.lubankt.Luban import com.github.dhaval2404.imagepicker.ImagePicker import com.github.dhaval2404.imagepicker.ImagePickerActivity -import com.github.dhaval2404.imagepicker.util.ExifDataCopier import com.github.dhaval2404.imagepicker.util.FileUtil -import com.github.dhaval2404.imagepicker.util.ImageUtil import java.io.File /** @@ -21,10 +18,6 @@ import java.io.File */ class CompressionProvider(activity: ImagePickerActivity) : BaseProvider(activity) { - companion object { - private val TAG = CompressionProvider::class.java.simpleName - } - private val mMaxWidth: Int private val mMaxHeight: Int private val mMaxFileSize: Long @@ -55,20 +48,6 @@ class CompressionProvider(activity: ImagePickerActivity) : BaseProvider(activity return mMaxFileSize > 0L } - /** - * Check if compression is required - * @param file File object to apply Compression - */ - private fun isCompressionRequired(file: File): Boolean { - val status = isCompressEnabled() && getSizeDiff(file) > 0L - if (!status && mMaxWidth > 0 && mMaxHeight > 0) { - // Check image resolution - val resolution = FileUtil.getImageResolution(file) - return resolution.first > mMaxWidth || resolution.second > mMaxHeight - } - return status - } - /** * Check if compression is required * @param uri Uri object to apply Compression @@ -83,10 +62,6 @@ class CompressionProvider(activity: ImagePickerActivity) : BaseProvider(activity return status } - private fun getSizeDiff(file: File): Long { - return file.length() - mMaxFileSize - } - private fun getSizeDiff(uri: Uri): Long { val length = FileUtil.getImageSize(this, uri) return length - mMaxFileSize @@ -106,128 +81,20 @@ class CompressionProvider(activity: ImagePickerActivity) : BaseProvider(activity */ @SuppressLint("StaticFieldLeak") private fun startCompressionWorker(uri: Uri) { - object : AsyncTask() { - override fun doInBackground(vararg params: Uri): File? { - // Perform operation in background - val file = FileUtil.getTempFile(this@CompressionProvider, params[0]) ?: return null - return startCompression(file) - } - - override fun onPostExecute(file: File?) { - super.onPostExecute(file) - if (file != null) { - // Post Result - handleResult(file) - } else { - // Post Error - setError(com.github.dhaval2404.imagepicker.R.string.error_failed_to_compress_image) - } - } - }.execute(uri) - } - - /** - * Check if compression required, And Apply compression until file size reach below Max Size. - */ - private fun startCompression(file: File): File? { - var newFile: File? = null - var attempt = 0 - var lastAttempt = 0 - do { - // Delete file if exist, fill will be exist in second loop. - newFile?.delete() - - newFile = applyCompression(file, attempt) - if (newFile == null) { - return if (attempt > 0) { - applyCompression(file, lastAttempt) - } else { - null + runCatching { mFileDir.mkdirs() } + Luban.with(activity) + .load(uri) + .ignoreBy(mMaxFileSize / 1024L) + .setOutPutDir("$mFileDir") + .compressObserver { + onSuccess = { compressFile -> + handleResult(compressFile) } - } - lastAttempt = attempt - - if (mMaxFileSize > 0) { - val diff = getSizeDiff(newFile) - // Log.i(TAG, "Size Diff:$diff") - attempt += when { - diff > 1024 * 1024 -> 3 - diff > 500 * 1024 -> 2 - else -> 1 + onError = { e, s -> + setError(com.github.dhaval2404.imagepicker.R.string.error_failed_to_compress_image) } - } else { - attempt++ } - } while (isCompressionRequired(newFile!!)) - - // Copy Exif Data - ExifDataCopier.copyExif(file, newFile) - - return newFile - } - - /** - * Compress the file - */ - private fun applyCompression(file: File, attempt: Int): File? { - val resList = resolutionList() - if (attempt >= resList.size) { - return null - } - - // Apply logic to get scaled bitmap resolution. - val resolution = resList[attempt] - var maxWidth = resolution[0] - var maxHeight = resolution[1] - - if (mMaxWidth > 0 && mMaxHeight > 0) { - if (maxWidth > mMaxWidth || maxHeight > mMaxHeight) { - maxHeight = mMaxHeight - maxWidth = mMaxWidth - } - } - // Log.d(TAG, "maxWidth:$maxWidth, maxHeight:$maxHeight") - - // Check file format - var format = Bitmap.CompressFormat.JPEG - if (file.absolutePath.endsWith(".png")) { - format = Bitmap.CompressFormat.PNG - } - - val extension = FileUtil.getImageExtension(file) - val compressFile: File? = FileUtil.getImageFile(fileDir = mFileDir, extension = extension) - return if (compressFile != null) { - ImageUtil.compressImage( - file, maxWidth.toFloat(), maxHeight.toFloat(), - format, compressFile.absolutePath - ) - } else { - null - } - } - - /** - * Image Resolution will be reduce with below parameters. - * - */ - private fun resolutionList(): List { - return listOf( - intArrayOf(2448, 3264), // 8.0 Megapixel - intArrayOf(2008, 3032), // 6.0 Megapixel - intArrayOf(1944, 2580), // 5.0 Megapixel - intArrayOf(1680, 2240), // 4.0 Megapixel - intArrayOf(1536, 2048), // 3.0 Megapixel - intArrayOf(1200, 1600), // 2.0 Megapixel - intArrayOf(1024, 1392), // 1.3 Megapixel - intArrayOf(960, 1280), // 1.0 Megapixel - intArrayOf(768, 1024), // 0.7 Megapixel - intArrayOf(600, 800), // 0.4 Megapixel - intArrayOf(480, 640), // 0.3 Megapixel - intArrayOf(240, 320), // 0.15 Megapixel - intArrayOf(120, 160), // 0.08 Megapixel - intArrayOf(60, 80), // 0.04 Megapixel - intArrayOf(30, 40) // 0.02 Megapixel - ) + .launch() } /**