Optimize I/O code using Okio - part 2 (#4372)
- Read license resource using Okio inside a coroutine (instead of the main thread) in `LicenseActivity` - Use Okio and its buffer system to copy ContentProvider streams and files to a temporary file in `MediaUploader.prepareMedia()` - Properly close the input file after copying it to a temporary file in `MediaUploader.prepareMedia()` - Properly close sink in case of null body source during file copy in `Uri.copyToFolder()` in `DraftHelper.kt` - Add comment explaining the current value of `DEFAULT_CHUNK_SIZE` in `UriRequestBody.kt` and indent the file properly - Replace hardcoded `Charset` and `Int` byte size with the proper constants, and align the `hashCode()` implementation with other `BitmapTransformation` implementations in `CompositeWithOpaqueBackground` - Properly close `InputStream` in case of error during Bitmap size decoding in `getImageSquarePixels()` - return `Int` instead of `Long` in `getImageSquarePixels()`, since the current code simply converts the `Int` result to a `Long` _after_ multiplication and not before (and `Int.MAX_VALUE` is already way above the maximum number of pixels a decoded Bitmap could return) - Simplify `getImageOrientation()` - Add explicit dependency to the Okio library and upgrade it to its latest version.
This commit is contained in:
parent
2504f42f7b
commit
f69cae2315
8 changed files with 77 additions and 76 deletions
|
|
@ -24,11 +24,11 @@ import android.graphics.ColorMatrix
|
|||
import android.graphics.ColorMatrixColorFilter
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Shader
|
||||
import com.bumptech.glide.load.Key
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||
import com.bumptech.glide.util.Util
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.charset.Charset
|
||||
import java.security.MessageDigest
|
||||
|
||||
/**
|
||||
|
|
@ -57,11 +57,11 @@ class CompositeWithOpaqueBackground(val backgroundColor: Int) : BitmapTransforma
|
|||
return false
|
||||
}
|
||||
|
||||
override fun hashCode() = Util.hashCode(ID.hashCode(), backgroundColor.hashCode())
|
||||
override fun hashCode() = Util.hashCode(ID.hashCode(), Util.hashCode(backgroundColor))
|
||||
|
||||
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
|
||||
messageDigest.update(ID_BYTES)
|
||||
messageDigest.update(ByteBuffer.allocate(4).putInt(backgroundColor.hashCode()).array())
|
||||
messageDigest.update(ByteBuffer.allocate(Int.SIZE_BYTES).putInt(backgroundColor).array())
|
||||
}
|
||||
|
||||
override fun transform(
|
||||
|
|
@ -111,7 +111,7 @@ class CompositeWithOpaqueBackground(val backgroundColor: Int) : BitmapTransforma
|
|||
@Suppress("unused")
|
||||
private const val TAG = "CompositeWithOpaqueBackground"
|
||||
private val ID = CompositeWithOpaqueBackground::class.qualifiedName!!
|
||||
private val ID_BYTES = ID.toByteArray(Charset.forName("UTF-8"))
|
||||
private val ID_BYTES = ID.toByteArray(Key.CHARSET)
|
||||
|
||||
/** Paint with a color filter that converts 8bpp alpha images to a 1bpp mask */
|
||||
private val EXTRACT_MASK_PAINT = Paint().apply {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import androidx.exifinterface.media.ExifInterface
|
|||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
|
@ -68,16 +67,18 @@ fun getMediaSize(contentResolver: ContentResolver, uri: Uri?): Long {
|
|||
}
|
||||
|
||||
@Throws(FileNotFoundException::class)
|
||||
fun getImageSquarePixels(contentResolver: ContentResolver, uri: Uri): Long {
|
||||
fun getImageSquarePixels(contentResolver: ContentResolver, uri: Uri): Int {
|
||||
val input = contentResolver.openInputStream(uri) ?: throw FileNotFoundException("Unavailable ContentProvider")
|
||||
|
||||
val options = BitmapFactory.Options()
|
||||
options.inJustDecodeBounds = true
|
||||
BitmapFactory.decodeStream(input, null, options)
|
||||
try {
|
||||
BitmapFactory.decodeStream(input, null, options)
|
||||
} finally {
|
||||
input.closeQuietly()
|
||||
}
|
||||
|
||||
input.closeQuietly()
|
||||
|
||||
return (options.outWidth * options.outHeight).toLong()
|
||||
return options.outWidth * options.outHeight
|
||||
}
|
||||
|
||||
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
|
||||
|
|
@ -147,30 +148,23 @@ fun reorientBitmap(bitmap: Bitmap?, orientation: Int): Bitmap? {
|
|||
}
|
||||
|
||||
fun getImageOrientation(uri: Uri, contentResolver: ContentResolver): Int {
|
||||
val inputStream: InputStream?
|
||||
try {
|
||||
inputStream = contentResolver.openInputStream(uri)
|
||||
} catch (e: FileNotFoundException) {
|
||||
Log.w(TAG, e)
|
||||
return ExifInterface.ORIENTATION_UNDEFINED
|
||||
}
|
||||
if (inputStream == null) {
|
||||
return ExifInterface.ORIENTATION_UNDEFINED
|
||||
}
|
||||
val exifInterface: ExifInterface
|
||||
try {
|
||||
exifInterface = ExifInterface(inputStream)
|
||||
val inputStream = contentResolver.openInputStream(uri)
|
||||
?: return ExifInterface.ORIENTATION_UNDEFINED
|
||||
|
||||
try {
|
||||
val exifInterface = ExifInterface(inputStream)
|
||||
return exifInterface.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL
|
||||
)
|
||||
} finally {
|
||||
inputStream.closeQuietly()
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Log.w(TAG, e)
|
||||
inputStream.closeQuietly()
|
||||
return ExifInterface.ORIENTATION_UNDEFINED
|
||||
}
|
||||
val orientation = exifInterface.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL
|
||||
)
|
||||
inputStream.closeQuietly()
|
||||
return orientation
|
||||
}
|
||||
|
||||
fun deleteStaleCachedMedia(mediaDirectory: File?) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue