For only with Files now
This commit is contained in:
parent
b31178683c
commit
544bff9f4f
|
@ -21,56 +21,46 @@ import android.content.Context
|
|||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Matrix
|
||||
import android.net.Uri
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.android.sdk.internal.di.SessionDownloadsDirectory
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class ImageCompressor @Inject constructor(
|
||||
@SessionDownloadsDirectory
|
||||
private val sessionCacheDirectory: File
|
||||
) {
|
||||
private val cacheFolder = File(sessionCacheDirectory, "MF")
|
||||
|
||||
internal class ImageCompressor @Inject constructor() {
|
||||
suspend fun compress(
|
||||
context: Context,
|
||||
imageUri: Uri,
|
||||
imageFile: File,
|
||||
desiredWidth: Int,
|
||||
desiredHeight: Int,
|
||||
desiredQuality: Int = 80): Uri {
|
||||
desiredQuality: Int = 80): File {
|
||||
return withContext(Dispatchers.IO) {
|
||||
val compressedBitmap = BitmapFactory.Options().run {
|
||||
inJustDecodeBounds = true
|
||||
decodeBitmap(context, imageUri, this)
|
||||
decodeBitmap(imageFile, this)
|
||||
inSampleSize = calculateInSampleSize(outWidth, outHeight, desiredWidth, desiredHeight)
|
||||
inJustDecodeBounds = false
|
||||
decodeBitmap(context, imageUri, this)?.let {
|
||||
rotateBitmap(context, imageUri, it)
|
||||
decodeBitmap(imageFile, this)?.let {
|
||||
rotateBitmap(imageFile, it)
|
||||
}
|
||||
} ?: return@withContext imageUri
|
||||
} ?: return@withContext imageFile
|
||||
|
||||
val destinationUri = createDestinationUri(context)
|
||||
val destinationFile = createDestinationFile(context)
|
||||
|
||||
runCatching {
|
||||
context.contentResolver.openOutputStream(destinationUri).use {
|
||||
destinationFile.outputStream().use {
|
||||
compressedBitmap.compress(Bitmap.CompressFormat.JPEG, desiredQuality, it)
|
||||
}
|
||||
}
|
||||
|
||||
return@withContext destinationUri
|
||||
return@withContext destinationFile
|
||||
}
|
||||
}
|
||||
|
||||
private fun rotateBitmap(context: Context, uri: Uri, bitmap: Bitmap): Bitmap {
|
||||
context.contentResolver.openInputStream(uri)?.use { inputStream ->
|
||||
private fun rotateBitmap(file: File, bitmap: Bitmap): Bitmap {
|
||||
file.inputStream().use { inputStream ->
|
||||
try {
|
||||
ExifInterface(inputStream).let { exifInfo ->
|
||||
val orientation = exifInfo.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
|
||||
|
@ -94,7 +84,7 @@ internal class ImageCompressor @Inject constructor(
|
|||
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Cannot read orientation: %s", uri.toString())
|
||||
Timber.e(e, "Cannot read orientation")
|
||||
}
|
||||
}
|
||||
return bitmap
|
||||
|
@ -118,9 +108,9 @@ internal class ImageCompressor @Inject constructor(
|
|||
return inSampleSize
|
||||
}
|
||||
|
||||
private fun decodeBitmap(context: Context, uri: Uri, options: BitmapFactory.Options = BitmapFactory.Options()): Bitmap? {
|
||||
private fun decodeBitmap(file: File, options: BitmapFactory.Options = BitmapFactory.Options()): Bitmap? {
|
||||
return try {
|
||||
context.contentResolver.openInputStream(uri)?.use { inputStream ->
|
||||
file.inputStream().use { inputStream ->
|
||||
BitmapFactory.decodeStream(inputStream, null, options)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -129,19 +119,7 @@ internal class ImageCompressor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun createDestinationUri(context: Context): Uri {
|
||||
val file = createTempFile()
|
||||
val authority = "${context.packageName}.mx-sdk.fileprovider"
|
||||
return FileProvider.getUriForFile(context, authority, file)
|
||||
}
|
||||
|
||||
private fun createTempFile(): File {
|
||||
if (!cacheFolder.exists()) cacheFolder.mkdirs()
|
||||
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
|
||||
return File.createTempFile(
|
||||
"${timeStamp}_", /* prefix */
|
||||
".jpg", /* suffix */
|
||||
cacheFolder /* directory */
|
||||
)
|
||||
private fun createDestinationFile(context: Context): File {
|
||||
return File.createTempFile(UUID.randomUUID().toString(), null, context.cacheDir)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,6 @@ package org.matrix.android.sdk.internal.session.content
|
|||
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import androidx.core.net.toFile
|
||||
import androidx.core.net.toUri
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
@ -129,7 +127,6 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||
inputStream.copyTo(it)
|
||||
}
|
||||
|
||||
// inputStream.use {
|
||||
var uploadedThumbnailUrl: String? = null
|
||||
var uploadedThumbnailEncryptedFileInfo: EncryptedFileInfo? = null
|
||||
|
||||
|
@ -181,9 +178,10 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||
val fileToUpload: File
|
||||
|
||||
if (attachment.type == ContentAttachmentData.Type.IMAGE && params.compressBeforeSending) {
|
||||
fileToUpload = imageCompressor.compress(context, workingFile.toUri(), MAX_IMAGE_SIZE, MAX_IMAGE_SIZE)
|
||||
.also { compressedUri ->
|
||||
context.contentResolver.openInputStream(compressedUri)?.use {
|
||||
fileToUpload = imageCompressor.compress(context, workingFile, MAX_IMAGE_SIZE, MAX_IMAGE_SIZE)
|
||||
.also { compressedFile ->
|
||||
// Get new Bitmap size
|
||||
compressedFile.inputStream().use {
|
||||
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
|
||||
val bitmap = BitmapFactory.decodeStream(it, null, options)
|
||||
val fileSize = bitmap?.byteCount ?: 0
|
||||
|
@ -194,7 +192,9 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||
)
|
||||
}
|
||||
}
|
||||
.toFile()
|
||||
|
||||
// we can delete workingFile
|
||||
tryThis { workingFile.delete() }
|
||||
} else {
|
||||
fileToUpload = workingFile
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
|
|||
}
|
||||
Timber.v("## FileService: cache storage updated")
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "## FileService: Failed to update fileservice cache")
|
||||
Timber.e(failure, "## FileService: Failed to update file cache")
|
||||
}
|
||||
|
||||
handleSuccess(params,
|
||||
|
|
Loading…
Reference in New Issue