fix: update swipe direction for reply functionality in MessageBubble
This commit is contained in:
@@ -3,8 +3,10 @@ package com.rosetta.messenger.utils
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.Matrix
|
||||
import android.net.Uri
|
||||
import android.util.Base64
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import com.vanniktech.blurhash.BlurHash
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -28,28 +30,33 @@ object MediaUtils {
|
||||
|
||||
/**
|
||||
* Конвертировать изображение из Uri в Base64 PNG
|
||||
* Автоматически сжимает большие изображения
|
||||
* Автоматически сжимает большие изображения и учитывает EXIF ориентацию
|
||||
*/
|
||||
suspend fun uriToBase64Image(context: Context, uri: Uri): String? = withContext(Dispatchers.IO) {
|
||||
try {
|
||||
|
||||
// Читаем EXIF ориентацию
|
||||
val orientation = getExifOrientation(context, uri)
|
||||
|
||||
// Открываем InputStream
|
||||
val inputStream: InputStream = context.contentResolver.openInputStream(uri)
|
||||
?: return@withContext null
|
||||
|
||||
// Декодируем изображение
|
||||
val originalBitmap = BitmapFactory.decodeStream(inputStream)
|
||||
var bitmap = BitmapFactory.decodeStream(inputStream)
|
||||
inputStream.close()
|
||||
|
||||
if (originalBitmap == null) {
|
||||
if (bitmap == null) {
|
||||
return@withContext null
|
||||
}
|
||||
|
||||
// Применяем EXIF ориентацию (поворот/отражение)
|
||||
bitmap = applyExifOrientation(bitmap, orientation)
|
||||
|
||||
// Масштабируем если слишком большое
|
||||
val scaledBitmap = scaleDownBitmap(originalBitmap, MAX_IMAGE_SIZE)
|
||||
if (scaledBitmap != originalBitmap) {
|
||||
originalBitmap.recycle()
|
||||
val scaledBitmap = scaleDownBitmap(bitmap, MAX_IMAGE_SIZE)
|
||||
if (scaledBitmap != bitmap) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +75,59 @@ object MediaUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Читает EXIF ориентацию из изображения
|
||||
*/
|
||||
private fun getExifOrientation(context: Context, uri: Uri): Int {
|
||||
return try {
|
||||
context.contentResolver.openInputStream(uri)?.use { inputStream ->
|
||||
val exif = ExifInterface(inputStream)
|
||||
exif.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL
|
||||
)
|
||||
} ?: ExifInterface.ORIENTATION_NORMAL
|
||||
} catch (e: Exception) {
|
||||
ExifInterface.ORIENTATION_NORMAL
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Применяет EXIF ориентацию к Bitmap (поворот/отражение)
|
||||
*/
|
||||
private fun applyExifOrientation(bitmap: Bitmap, orientation: Int): Bitmap {
|
||||
val matrix = Matrix()
|
||||
|
||||
when (orientation) {
|
||||
ExifInterface.ORIENTATION_ROTATE_90 -> matrix.postRotate(90f)
|
||||
ExifInterface.ORIENTATION_ROTATE_180 -> matrix.postRotate(180f)
|
||||
ExifInterface.ORIENTATION_ROTATE_270 -> matrix.postRotate(270f)
|
||||
ExifInterface.ORIENTATION_FLIP_HORIZONTAL -> matrix.preScale(-1f, 1f)
|
||||
ExifInterface.ORIENTATION_FLIP_VERTICAL -> matrix.preScale(1f, -1f)
|
||||
ExifInterface.ORIENTATION_TRANSPOSE -> {
|
||||
matrix.postRotate(90f)
|
||||
matrix.preScale(-1f, 1f)
|
||||
}
|
||||
ExifInterface.ORIENTATION_TRANSVERSE -> {
|
||||
matrix.postRotate(270f)
|
||||
matrix.preScale(-1f, 1f)
|
||||
}
|
||||
else -> return bitmap // ORIENTATION_NORMAL или неизвестный
|
||||
}
|
||||
|
||||
return try {
|
||||
val rotatedBitmap = Bitmap.createBitmap(
|
||||
bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true
|
||||
)
|
||||
if (rotatedBitmap != bitmap) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
rotatedBitmap
|
||||
} catch (e: Exception) {
|
||||
bitmap
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерировать Blurhash для изображения
|
||||
*/
|
||||
@@ -203,6 +263,7 @@ object MediaUtils {
|
||||
|
||||
/**
|
||||
* Получить размеры изображения из Uri без полной загрузки в память
|
||||
* Учитывает EXIF ориентацию для правильных width/height
|
||||
*/
|
||||
fun getImageDimensions(context: Context, uri: Uri): Pair<Int, Int> {
|
||||
return try {
|
||||
@@ -216,6 +277,17 @@ object MediaUtils {
|
||||
var width = options.outWidth
|
||||
var height = options.outHeight
|
||||
|
||||
// Учитываем EXIF ориентацию - если поворот 90 или 270, меняем местами width/height
|
||||
val orientation = getExifOrientation(context, uri)
|
||||
if (orientation == ExifInterface.ORIENTATION_ROTATE_90 ||
|
||||
orientation == ExifInterface.ORIENTATION_ROTATE_270 ||
|
||||
orientation == ExifInterface.ORIENTATION_TRANSPOSE ||
|
||||
orientation == ExifInterface.ORIENTATION_TRANSVERSE) {
|
||||
val temp = width
|
||||
width = height
|
||||
height = temp
|
||||
}
|
||||
|
||||
// Учитываем масштабирование (как в uriToBase64Image)
|
||||
if (width > MAX_IMAGE_SIZE || height > MAX_IMAGE_SIZE) {
|
||||
val ratio = width.toFloat() / height.toFloat()
|
||||
|
||||
Reference in New Issue
Block a user