Merge pull request #1547 from vector-im/feature/fix_compress_images

Compress images before sending
This commit is contained in:
Onuray Sahin 2020-06-26 15:12:27 +03:00 committed by GitHub
commit 90804f7625
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 45 additions and 2 deletions

View File

@ -13,6 +13,7 @@ Bugfix 🐛:
- Incomplete predicate in RealmCryptoStore#getOutgoingRoomKeyRequest (#1519) - Incomplete predicate in RealmCryptoStore#getOutgoingRoomKeyRequest (#1519)
- User could not redact message that they have sent (#1543) - User could not redact message that they have sent (#1543)
- Use vendor prefix for non merged MSC (#1537) - Use vendor prefix for non merged MSC (#1537)
- Compress images before sending (#1333)
Translations 🗣: Translations 🗣:
- -

View File

@ -17,9 +17,12 @@
package im.vector.matrix.android.internal.session.content package im.vector.matrix.android.internal.session.content
import android.content.Context import android.content.Context
import android.graphics.BitmapFactory
import androidx.work.CoroutineWorker import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.squareup.moshi.JsonClass import com.squareup.moshi.JsonClass
import id.zelory.compressor.Compressor
import id.zelory.compressor.constraint.default
import im.vector.matrix.android.api.session.content.ContentAttachmentData import im.vector.matrix.android.api.session.content.ContentAttachmentData
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.toContent import im.vector.matrix.android.api.session.events.model.toContent
@ -38,6 +41,10 @@ import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import im.vector.matrix.android.internal.worker.getSessionComponent import im.vector.matrix.android.internal.worker.getSessionComponent
import timber.log.Timber import timber.log.Timber
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.util.UUID
import javax.inject.Inject import javax.inject.Inject
private data class NewImageAttributes( private data class NewImageAttributes(
@ -154,18 +161,53 @@ internal class UploadContentWorker(val context: Context, params: WorkerParameter
var uploadedFileEncryptedFileInfo: EncryptedFileInfo? = null var uploadedFileEncryptedFileInfo: EncryptedFileInfo? = null
return try { return try {
// Compressor library works with File instead of Uri for now. Since Scoped Storage doesn't allow us to access files directly, we should
// copy it to a cache folder by using InputStream and OutputStream.
// https://github.com/zetbaitsu/Compressor/pull/150
// As soon as the above PR is merged, we can use attachment.queryUri instead of creating a cacheFile.
var cacheFile = File.createTempFile(attachment.name ?: UUID.randomUUID().toString(), ".jpg", context.cacheDir)
cacheFile.parentFile?.mkdirs()
if (cacheFile.exists()) {
cacheFile.delete()
}
cacheFile.createNewFile()
cacheFile.deleteOnExit()
val outputStream = FileOutputStream(cacheFile)
outputStream.use {
inputStream.copyTo(outputStream)
}
if (attachment.type == ContentAttachmentData.Type.IMAGE && params.compressBeforeSending) {
cacheFile = Compressor.compress(context, cacheFile) {
default(
width = MAX_IMAGE_SIZE,
height = MAX_IMAGE_SIZE
)
}.also { compressedFile ->
val options = BitmapFactory.Options().apply { inJustDecodeBounds = true }
BitmapFactory.decodeFile(compressedFile.absolutePath, options)
val fileSize = compressedFile.length().toInt()
newImageAttributes = NewImageAttributes(
options.outWidth,
options.outHeight,
fileSize
)
}
}
val contentUploadResponse = if (params.isEncrypted) { val contentUploadResponse = if (params.isEncrypted) {
Timber.v("Encrypt file") Timber.v("Encrypt file")
notifyTracker(params) { contentUploadStateTracker.setEncrypting(it) } notifyTracker(params) { contentUploadStateTracker.setEncrypting(it) }
val encryptionResult = MXEncryptedAttachments.encryptAttachment(inputStream, attachment.getSafeMimeType()) val encryptionResult = MXEncryptedAttachments.encryptAttachment(FileInputStream(cacheFile), attachment.getSafeMimeType())
uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo uploadedFileEncryptedFileInfo = encryptionResult.encryptedFileInfo
fileUploader fileUploader
.uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, "application/octet-stream", progressListener) .uploadByteArray(encryptionResult.encryptedByteArray, attachment.name, "application/octet-stream", progressListener)
} else { } else {
fileUploader fileUploader
.uploadByteArray(inputStream.readBytes(), attachment.name, attachment.getSafeMimeType(), progressListener) .uploadFile(cacheFile, attachment.name, attachment.getSafeMimeType(), progressListener)
} }
handleSuccess(params, handleSuccess(params,