Skip to content

Commit 0ee338c

Browse files
committed
Optimize CompressionProvider
1 parent 1ef2d9c commit 0ee338c

2 files changed

Lines changed: 13 additions & 140 deletions

File tree

imagepicker/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ dependencies {
5050

5151
//More Info: https://github.com/Yalantis/uCrop
5252
implementation 'com.github.yalantis:ucrop:2.2.6'
53+
implementation "io.github.lucksiege:compress:v3.11.2"
5354

5455
testImplementation 'junit:junit:4.13.2'
5556
androidTestImplementation 'androidx.test.ext:junit:1.1.2'

imagepicker/src/main/kotlin/com/github/dhaval2404/imagepicker/provider/CompressionProvider.kt

Lines changed: 12 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
package com.github.dhaval2404.imagepicker.provider
22

33
import android.annotation.SuppressLint
4-
import android.graphics.Bitmap
54
import android.net.Uri
6-
import android.os.AsyncTask
75
import android.os.Bundle
86
import com.github.dhaval2404.imagepicker.ImagePicker
97
import com.github.dhaval2404.imagepicker.ImagePickerActivity
10-
import com.github.dhaval2404.imagepicker.util.ExifDataCopier
118
import com.github.dhaval2404.imagepicker.util.FileUtil
12-
import com.github.dhaval2404.imagepicker.util.ImageUtil
9+
import top.zibin.luban.Luban
10+
import top.zibin.luban.OnNewCompressListener
1311
import java.io.File
1412

1513
/**
@@ -21,10 +19,6 @@ import java.io.File
2119
*/
2220
class CompressionProvider(activity: ImagePickerActivity) : BaseProvider(activity) {
2321

24-
companion object {
25-
private val TAG = CompressionProvider::class.java.simpleName
26-
}
27-
2822
private val mMaxWidth: Int
2923
private val mMaxHeight: Int
3024
private val mMaxFileSize: Long
@@ -55,20 +49,6 @@ class CompressionProvider(activity: ImagePickerActivity) : BaseProvider(activity
5549
return mMaxFileSize > 0L
5650
}
5751

58-
/**
59-
* Check if compression is required
60-
* @param file File object to apply Compression
61-
*/
62-
private fun isCompressionRequired(file: File): Boolean {
63-
val status = isCompressEnabled() && getSizeDiff(file) > 0L
64-
if (!status && mMaxWidth > 0 && mMaxHeight > 0) {
65-
// Check image resolution
66-
val resolution = FileUtil.getImageResolution(file)
67-
return resolution.first > mMaxWidth || resolution.second > mMaxHeight
68-
}
69-
return status
70-
}
71-
7252
/**
7353
* Check if compression is required
7454
* @param uri Uri object to apply Compression
@@ -83,10 +63,6 @@ class CompressionProvider(activity: ImagePickerActivity) : BaseProvider(activity
8363
return status
8464
}
8565

86-
private fun getSizeDiff(file: File): Long {
87-
return file.length() - mMaxFileSize
88-
}
89-
9066
private fun getSizeDiff(uri: Uri): Long {
9167
val length = FileUtil.getImageSize(this, uri)
9268
return length - mMaxFileSize
@@ -106,128 +82,24 @@ class CompressionProvider(activity: ImagePickerActivity) : BaseProvider(activity
10682
*/
10783
@SuppressLint("StaticFieldLeak")
10884
private fun startCompressionWorker(uri: Uri) {
109-
object : AsyncTask<Uri, Void, File>() {
110-
override fun doInBackground(vararg params: Uri): File? {
111-
// Perform operation in background
112-
val file = FileUtil.getTempFile(this@CompressionProvider, params[0]) ?: return null
113-
return startCompression(file)
85+
Luban.with(activity).load(uri).ignoreBy(
86+
(mMaxFileSize / 1024L).toInt()
87+
).setTargetDir("$mFileDir").setCompressListener(object : OnNewCompressListener {
88+
override fun onStart() {
11489
}
11590

116-
override fun onPostExecute(file: File?) {
117-
super.onPostExecute(file)
118-
if (file != null) {
119-
// Post Result
120-
handleResult(file)
91+
override fun onSuccess(source: String?, compressFile: File?) {
92+
if (compressFile != null) {
93+
handleResult(compressFile)
12194
} else {
122-
// Post Error
12395
setError(com.github.dhaval2404.imagepicker.R.string.error_failed_to_compress_image)
12496
}
12597
}
126-
}.execute(uri)
127-
}
12898

129-
/**
130-
* Check if compression required, And Apply compression until file size reach below Max Size.
131-
*/
132-
private fun startCompression(file: File): File? {
133-
var newFile: File? = null
134-
var attempt = 0
135-
var lastAttempt = 0
136-
do {
137-
// Delete file if exist, fill will be exist in second loop.
138-
newFile?.delete()
139-
140-
newFile = applyCompression(file, attempt)
141-
if (newFile == null) {
142-
return if (attempt > 0) {
143-
applyCompression(file, lastAttempt)
144-
} else {
145-
null
146-
}
147-
}
148-
lastAttempt = attempt
149-
150-
if (mMaxFileSize > 0) {
151-
val diff = getSizeDiff(newFile)
152-
// Log.i(TAG, "Size Diff:$diff")
153-
attempt += when {
154-
diff > 1024 * 1024 -> 3
155-
diff > 500 * 1024 -> 2
156-
else -> 1
157-
}
158-
} else {
159-
attempt++
99+
override fun onError(source: String?, e: Throwable?) {
100+
setError(com.github.dhaval2404.imagepicker.R.string.error_failed_to_compress_image)
160101
}
161-
} while (isCompressionRequired(newFile!!))
162-
163-
// Copy Exif Data
164-
ExifDataCopier.copyExif(file, newFile)
165-
166-
return newFile
167-
}
168-
169-
/**
170-
* Compress the file
171-
*/
172-
private fun applyCompression(file: File, attempt: Int): File? {
173-
val resList = resolutionList()
174-
if (attempt >= resList.size) {
175-
return null
176-
}
177-
178-
// Apply logic to get scaled bitmap resolution.
179-
val resolution = resList[attempt]
180-
var maxWidth = resolution[0]
181-
var maxHeight = resolution[1]
182-
183-
if (mMaxWidth > 0 && mMaxHeight > 0) {
184-
if (maxWidth > mMaxWidth || maxHeight > mMaxHeight) {
185-
maxHeight = mMaxHeight
186-
maxWidth = mMaxWidth
187-
}
188-
}
189-
// Log.d(TAG, "maxWidth:$maxWidth, maxHeight:$maxHeight")
190-
191-
// Check file format
192-
var format = Bitmap.CompressFormat.JPEG
193-
if (file.absolutePath.endsWith(".png")) {
194-
format = Bitmap.CompressFormat.PNG
195-
}
196-
197-
val extension = FileUtil.getImageExtension(file)
198-
val compressFile: File? = FileUtil.getImageFile(fileDir = mFileDir, extension = extension)
199-
return if (compressFile != null) {
200-
ImageUtil.compressImage(
201-
file, maxWidth.toFloat(), maxHeight.toFloat(),
202-
format, compressFile.absolutePath
203-
)
204-
} else {
205-
null
206-
}
207-
}
208-
209-
/**
210-
* Image Resolution will be reduce with below parameters.
211-
*
212-
*/
213-
private fun resolutionList(): List<IntArray> {
214-
return listOf(
215-
intArrayOf(2448, 3264), // 8.0 Megapixel
216-
intArrayOf(2008, 3032), // 6.0 Megapixel
217-
intArrayOf(1944, 2580), // 5.0 Megapixel
218-
intArrayOf(1680, 2240), // 4.0 Megapixel
219-
intArrayOf(1536, 2048), // 3.0 Megapixel
220-
intArrayOf(1200, 1600), // 2.0 Megapixel
221-
intArrayOf(1024, 1392), // 1.3 Megapixel
222-
intArrayOf(960, 1280), // 1.0 Megapixel
223-
intArrayOf(768, 1024), // 0.7 Megapixel
224-
intArrayOf(600, 800), // 0.4 Megapixel
225-
intArrayOf(480, 640), // 0.3 Megapixel
226-
intArrayOf(240, 320), // 0.15 Megapixel
227-
intArrayOf(120, 160), // 0.08 Megapixel
228-
intArrayOf(60, 80), // 0.04 Megapixel
229-
intArrayOf(30, 40) // 0.02 Megapixel
230-
)
102+
}).launch()
231103
}
232104

233105
/**

0 commit comments

Comments
 (0)