diff --git a/app/build.gradle b/app/build.gradle index 8e6973e..761086f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,8 +28,8 @@ dependencies { implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0' implementation 'androidx.appcompat:appcompat:1.1.0' - //implementation project(':compressor') - implementation 'id.zelory:compressor:3.0.0' + implementation project(':compressor') +// implementation 'id.zelory:compressor:3.0.0' testImplementation 'junit:junit:4.12' } diff --git a/app/src/main/java/id/zelory/compressor/sample/MainActivity.kt b/app/src/main/java/id/zelory/compressor/sample/MainActivity.kt index e0141af..b3f83fa 100644 --- a/app/src/main/java/id/zelory/compressor/sample/MainActivity.kt +++ b/app/src/main/java/id/zelory/compressor/sample/MainActivity.kt @@ -4,6 +4,7 @@ import android.content.Intent import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Color +import android.net.Uri import android.os.Bundle import android.os.Environment import android.util.Log @@ -45,6 +46,7 @@ class MainActivity : AppCompatActivity() { } private var actualImage: File? = null + private var actualImageUri: Uri? = null private var compressedImage: File? = null override fun onCreate(savedInstanceState: Bundle?) { @@ -68,7 +70,7 @@ class MainActivity : AppCompatActivity() { } private fun compressImage() { - actualImage?.let { imageFile -> + actualImageUri?.let { imageFile -> lifecycleScope.launch { // Default compression compressedImage = Compressor.compress(this@MainActivity, imageFile) @@ -125,6 +127,7 @@ class MainActivity : AppCompatActivity() { return } try { + actualImageUri = data.data actualImage = FileUtil.from(this, data.data)?.also { actualImageView.setImageBitmap(loadBitmap(it)) actualSizeTextView.text = String.format("Size : %s", getReadableFileSize(it.length())) diff --git a/compressor/src/main/java/id/zelory/compressor/Compressor.kt b/compressor/src/main/java/id/zelory/compressor/Compressor.kt index bfc5ffe..9d422da 100644 --- a/compressor/src/main/java/id/zelory/compressor/Compressor.kt +++ b/compressor/src/main/java/id/zelory/compressor/Compressor.kt @@ -1,6 +1,7 @@ package id.zelory.compressor import android.content.Context +import android.net.Uri import id.zelory.compressor.constraint.Compression import id.zelory.compressor.constraint.default import kotlinx.coroutines.Dispatchers @@ -30,4 +31,20 @@ object Compressor { } return@withContext result } + + suspend fun compress( + context: Context, + imageUri: Uri, + coroutineContext: CoroutineContext = Dispatchers.IO, + compressionPatch: Compression.() -> Unit = { default() } + ) = withContext(coroutineContext) { + val compression = Compression().apply(compressionPatch) + var result = copyToCache(context, imageUri) + compression.constraints.forEach { constraint -> + while (constraint.isSatisfied(result).not()) { + result = constraint.satisfy(result) + } + } + return@withContext result + } } \ No newline at end of file diff --git a/compressor/src/main/java/id/zelory/compressor/Util.kt b/compressor/src/main/java/id/zelory/compressor/Util.kt index bcb1cb3..1dc7200 100644 --- a/compressor/src/main/java/id/zelory/compressor/Util.kt +++ b/compressor/src/main/java/id/zelory/compressor/Util.kt @@ -1,12 +1,16 @@ package id.zelory.compressor +import android.content.ContentResolver import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Matrix import android.media.ExifInterface +import android.net.Uri +import android.provider.OpenableColumns import java.io.File import java.io.FileOutputStream +import java.net.URISyntaxException /** * Created on : January 24, 2020 @@ -82,6 +86,31 @@ internal fun copyToCache(context: Context, imageFile: File): File { return imageFile.copyTo(File("${cachePath(context)}${imageFile.name}"), true) } +internal fun copyToCache(context: Context, imageUri: Uri): File { + val fileName = when (imageUri.scheme) { + ContentResolver.SCHEME_FILE -> File(requireNotNull(imageUri.path) { "Uri path is null: ${imageUri.path}" }).name + ContentResolver.SCHEME_CONTENT -> { + context.contentResolver.query(imageUri, null, null, null, null) + ?.use { cursor -> + val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) + cursor.moveToFirst() + cursor.getString(nameIndex) + } ?: throw NoSuchFieldException("File not found: $imageUri") + } + else -> throw IllegalArgumentException("Uri scheme not support: ${imageUri.scheme}") + } + val target = File("${cachePath(context)}${fileName}").apply { mkdirs() } + if (target.exists() && !target.delete()) { + throw FileAlreadyExistsException(file = target, reason = "Tried to overwrite the destination, but failed to delete it.") + } + context.contentResolver.openInputStream(imageUri)!!.use { input -> + target.outputStream().use { output -> + input.copyTo(output) + } + } + return target +} + fun overWrite(imageFile: File, bitmap: Bitmap, format: Bitmap.CompressFormat = imageFile.compressFormat(), quality: Int = 100): File { val result = if (format == imageFile.compressFormat()) { imageFile