Android BitmapFactory.decodeFile vs ImageDecoder.decodeBitmap,Kotlin
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
import android.content.ContentUris
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.ImageDecoder
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.io.File
class ImageActivity : AppCompatActivity() {
companion object {
const val TAG = "fly/ImageActivity"
const val SIZE = 400
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val ctx = this
lifecycleScope.launch(Dispatchers.IO) {
val imgList = readAllImage(ctx)
val videoList = readAllVideo(ctx)
Log.d(TAG, "readAllImage size=${imgList.size}")
Log.d(TAG, "readAllVideo size=${videoList.size}")
val lists = arrayListOf<MyData>()
lists.addAll(imgList)
lists.addAll(videoList)
lists.shuffle()
var ec = 0
var t = System.currentTimeMillis()
lists.take(3000).forEachIndexed { index, myData ->
val b = bitmapFactoryDecodeFile(myData.path)
if (b == null) {
ec++
}
}
val ec1 = ec
val t1 = System.currentTimeMillis() - t
ec = 0
t = System.currentTimeMillis()
lists.take(3000).forEachIndexed { index, myData ->
try {
imageDecoder(myData.path)
} catch (e: Exception) {
ec++
}
}
val ec2 = ec
val t2 = System.currentTimeMillis() - t
Log.d(TAG, "BitmapFactory 耗时=${t1}ms $ec1")
Log.d(TAG, "ImageDecoder 耗时=${t2}ms $ec2")
}
}
private fun bitmapFactoryDecodeFile(path: String): Bitmap? {
val option = BitmapFactory.Options()
option.outWidth = SIZE
option.outHeight = SIZE
option.inPreferredConfig = Bitmap.Config.ARGB_8888
return BitmapFactory.decodeFile(path, option)
}
private fun imageDecoder(path: String) {
val src = ImageDecoder.createSource(File(path))
ImageDecoder.decodeBitmap(src, object : ImageDecoder.OnHeaderDecodedListener {
override fun onHeaderDecoded(decoder: ImageDecoder, info: ImageDecoder.ImageInfo, source: ImageDecoder.Source) {
decoder.setTargetSize(SIZE, SIZE)
//decoder.isMutableRequired = false
}
})
}
class MyData(var path: String, var uri: Uri)
private fun readAllImage(ctx: Context): ArrayList<MyData> {
val photos = ArrayList<MyData>()
//读取所有图
val cursor = ctx.contentResolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null
)
while (cursor!!.moveToNext()) {
//路径
val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))
val id = cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID)
val imageUri: Uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cursor.getLong(id))
//名称
//val name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
//大小
//val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE))
photos.add(MyData(path, imageUri))
}
cursor.close()
return photos
}
private fun readAllVideo(context: Context): ArrayList<MyData> {
val videos = ArrayList<MyData>()
//读取视频Video
val cursor = context.contentResolver.query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
null,
null,
null,
null
)
while (cursor!!.moveToNext()) {
//路径
val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA))
val id = cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID)
val videoUri: Uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cursor.getLong(id))
//名称
//val name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME))
//大小
//val size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE))
videos.add(MyData(path, videoUri))
}
cursor.close()
return videos
}
}
Android ImageDecoder把瘦高/扁平大图相当于fitCenter模式decode成目标小尺寸Bitmap,Kotlin-CSDN博客文章浏览阅读580次,点赞3次,收藏10次。Android拼接合并图片生成长图代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放。Android拼接合并图片生成长图代码实现合并两张图片,以第一张图片的宽度为标准,如果被合并的第二张图片宽度和第一张不同,那么就以第一张图片的宽度为准线,对第二张图片进行缩放。基础上,把剪切的区域从矩形Rect变为圆形的Path,当手指在上面的ImageView移动时候,下面同等大小对应的坐标区域显示“剪切”出来的圆形图。_android imagedecoder
https://blog.csdn.net/zhangphil/article/details/140153545