Skip to content
This repository was archived by the owner on Jun 7, 2020. It is now read-only.

Commit a9985b2

Browse files
authored
Merge pull request #1810 from RocketChat/improvement/image-compression
[IMPROVEMENT] Image compression
2 parents ec79b32 + a3d7110 commit a9985b2

4 files changed

Lines changed: 93 additions & 18 deletions

File tree

app/src/main/java/chat/rocket/android/chatroom/presentation/ChatRoomPresenter.kt

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import chat.rocket.android.server.domain.useRealName
3535
import chat.rocket.android.server.infraestructure.ConnectionManagerFactory
3636
import chat.rocket.android.server.infraestructure.state
3737
import chat.rocket.android.util.extension.compressImageAndGetByteArray
38+
import chat.rocket.android.util.extension.getByteArray
3839
import chat.rocket.android.util.extension.launchUI
3940
import chat.rocket.android.util.extensions.avatarUrl
4041
import chat.rocket.android.util.retryIO
@@ -80,6 +81,7 @@ import kotlinx.coroutines.experimental.launch
8081
import kotlinx.coroutines.experimental.withContext
8182
import org.threeten.bp.Instant
8283
import timber.log.Timber
84+
import java.io.InputStream
8385
import java.util.*
8486
import javax.inject.Inject
8587

@@ -346,15 +348,51 @@ class ChatRoomPresenter @Inject constructor(
346348
view.showFileSelection(settings.uploadMimeTypeFilter())
347349
}
348350

349-
fun uploadFile(roomId: String, uri: Uri, msg: String, bitmap: Bitmap? = null) {
351+
fun uploadImage(roomId: String, mimeType: String, uri: Uri, bitmap: Bitmap, msg: String) {
350352
launchUI(strategy) {
351353
view.showLoading()
352354
try {
353355
withContext(DefaultDispatcher) {
354356
val fileName = uriInteractor.getFileName(uri) ?: uri.toString()
355-
val mimeType = uriInteractor.getMimeType(uri)
356-
val byteArray = bitmap?.compressImageAndGetByteArray(mimeType)
357-
val fileSize = byteArray?.size ?: uriInteractor.getFileSize(uri)
357+
if (fileName.isEmpty()) {
358+
view.showInvalidFileMessage()
359+
} else {
360+
val byteArray =
361+
bitmap.getByteArray(mimeType, 100, settings.uploadMaxFileSize())
362+
retryIO("uploadFile($roomId, $fileName, $mimeType") {
363+
client.uploadFile(
364+
roomId,
365+
fileName,
366+
mimeType,
367+
msg,
368+
description = fileName
369+
) {
370+
byteArray.inputStream()
371+
}
372+
}
373+
374+
logMediaUploaded(mimeType)
375+
}
376+
}
377+
} catch (ex: Exception) {
378+
Timber.d(ex, "Error uploading image")
379+
when (ex) {
380+
is RocketChatException -> view.showMessage(ex)
381+
else -> view.showGenericErrorMessage()
382+
}
383+
} finally {
384+
view.hideLoading()
385+
}
386+
}
387+
}
388+
389+
fun uploadFile(roomId: String, mimeType: String, uri: Uri, msg: String) {
390+
launchUI(strategy) {
391+
view.showLoading()
392+
try {
393+
withContext(DefaultDispatcher) {
394+
val fileName = uriInteractor.getFileName(uri) ?: uri.toString()
395+
val fileSize = uriInteractor.getFileSize(uri)
358396
val maxFileSizeAllowed = settings.uploadMaxFileSize()
359397

360398
when {
@@ -370,7 +408,7 @@ class ChatRoomPresenter @Inject constructor(
370408
msg,
371409
description = fileName
372410
) {
373-
byteArray?.inputStream() ?: uriInteractor.getInputStream(uri)
411+
uriInteractor.getInputStream(uri)
374412
}
375413
}
376414
logMediaUploaded(mimeType)

app/src/main/java/chat/rocket/android/chatroom/ui/Dialog.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@ import androidx.core.view.isVisible
77
import chat.rocket.android.emoji.internal.GlideApp
88
import chat.rocket.android.util.extensions.getFileName
99
import chat.rocket.android.util.extensions.getMimeType
10-
import com.bumptech.glide.load.resource.gif.GifDrawable
10+
import chat.rocket.common.util.ifNull
1111
import com.bumptech.glide.request.target.SimpleTarget
1212
import com.bumptech.glide.request.transition.Transition
1313

1414
fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) {
1515
imagePreview.isVisible = false
1616
audioVideoAttachment.isVisible = false
1717
textFile.isVisible = false
18+
lateinit var mimeType: String
1819
var bitmap: Bitmap? = null
1920

2021
activity?.let { context ->
21-
uri.getMimeType(context).let { mimeType ->
22+
uri.getMimeType(context).let {
23+
mimeType = it
2224
description.text.clear()
2325
when {
2426
mimeType.startsWith("image") -> {
@@ -27,15 +29,13 @@ fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) {
2729
.with(context)
2830
.asGif()
2931
.load(uri)
30-
.override(imagePreview.width, imagePreview.height)
3132
.fitCenter()
3233
.into(imagePreview)
3334
} else {
3435
GlideApp
3536
.with(context)
3637
.asBitmap()
3738
.load(uri)
38-
.override(imagePreview.width, imagePreview.height)
3939
.fitCenter()
4040
.into(object : SimpleTarget<Bitmap>() {
4141
override fun onResourceReady(
@@ -59,12 +59,22 @@ fun ChatRoomFragment.showFileAttachmentDialog(uri: Uri) {
5959
}
6060

6161
sendButton.setOnClickListener {
62-
presenter.uploadFile(
63-
chatRoomId,
64-
uri,
65-
(citation ?: "") + description.text.toString(),
66-
bitmap
67-
)
62+
bitmap?.let { bitmap ->
63+
presenter.uploadImage(
64+
chatRoomId,
65+
mimeType,
66+
uri,
67+
bitmap,
68+
(citation ?: "") + description.text.toString()
69+
)
70+
}.ifNull {
71+
presenter.uploadFile(
72+
chatRoomId,
73+
mimeType,
74+
uri,
75+
(citation ?: "") + description.text.toString()
76+
)
77+
}
6878
alertDialog.dismiss()
6979
}
7080
cancelButton.setOnClickListener { alertDialog.dismiss() }

app/src/main/java/chat/rocket/android/helper/MessageParser.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import android.text.style.ReplacementSpan
1313
import android.view.View
1414
import androidx.core.content.res.ResourcesCompat
1515
import chat.rocket.android.R
16+
import androidx.core.util.PatternsCompat
1617
import chat.rocket.android.chatroom.ui.StrikethroughDelimiterProcessor
1718
import chat.rocket.android.emoji.EmojiParser
1819
import chat.rocket.android.emoji.EmojiRepository

util/src/main/java/chat/rocket/android/util/extension/Image.kt

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,46 @@ suspend fun Bitmap.compressImageAndGetInputStream(mimeType: String): InputStream
3232
return inputStream
3333
}
3434

35+
/**
36+
* Returns a [ByteArray] of a [Bitmap].
37+
*
38+
* @param mimeType The MIME type of the [Bitmap].
39+
* @param quality The quality of the [Bitmap] for the resulting [ByteArray].
40+
* @param maxFileSizeAllowed The max file size allowed by the server. Note: The [quality] will be
41+
* decreased minus 10 until the [ByteArray] size fits the [maxFileSizeAllowed] value.
42+
* @return A [ByteArray] of a [Bitmap]
43+
*/
44+
suspend fun Bitmap.getByteArray(
45+
mimeType: String,
46+
quality: Int,
47+
maxFileSizeAllowed: Int
48+
): ByteArray {
49+
lateinit var byteArray: ByteArray
50+
51+
compressImageAndGetByteArray(mimeType, quality)?.let {
52+
if (it.size > maxFileSizeAllowed && maxFileSizeAllowed !in -1..0) {
53+
getByteArray(mimeType, quality - 10, maxFileSizeAllowed)
54+
} else {
55+
byteArray = it
56+
}
57+
}
58+
59+
return byteArray
60+
}
61+
3562
/**
3663
* Compress a [Bitmap] image.
3764
*
3865
* @param mimeType The MimeType of what the compressed image should be.
3966
* @return An [ByteArray] of a compressed image, otherwise null if the compression couldn't be done.
4067
*/
41-
suspend fun Bitmap.compressImageAndGetByteArray(mimeType: String): ByteArray? {
68+
suspend fun Bitmap.compressImageAndGetByteArray(mimeType: String, quality: Int = 100): ByteArray? {
4269
var byteArray: ByteArray? = null
4370

4471
withContext(DefaultDispatcher) {
4572
val byteArrayOutputStream = ByteArrayOutputStream()
46-
// TODO: Add an option the the app to the user be able to select the quality of the compressed image
4773
val isCompressed =
48-
this.compress(mimeType.getCompressFormat(), 70, byteArrayOutputStream)
74+
this.compress(mimeType.getCompressFormat(), quality, byteArrayOutputStream)
4975
if (isCompressed) {
5076
byteArray = byteArrayOutputStream.toByteArray()
5177
}

0 commit comments

Comments
 (0)