Medya küçük resimleri, kullanıcılara resim ve videoların hızlı bir görsel önizlemesini sunar. Böylece, uygulama arayüzünü görsel açıdan daha ilgi çekici ve etkileşimli hale getirirken daha hızlı gezinme olanağı sağlar. Küçük resimler tam boyutlu medyalara kıyasla daha küçük olduğundan, medya tarama performansını artırırken bellek, depolama alanı ve bant genişliğinden tasarruf etmenize yardımcı olur.
Dosya türüne ve uygulamanızdaki medya öğelerinize sahip olduğunuz dosya erişimine bağlı olarak çeşitli şekillerde küçük resim oluşturabilirsiniz.
Resim yükleme kitaplığı kullanarak küçük resim oluşturma
Resim yükleme kitaplıkları, işin büyük bir kısmını sizin yerinize halleder. ele alabilirler. kaynak medyayı yerelden veya ağdan getirme mantığıyla birlikte önbelleğe alma Uri'ye dayalı kaynaktır. Aşağıdaki kod, Coil resim yükleme kitaplığı hem resimlerde hem de videolarda çalışır. ve yerel kaynak veya ağ kaynağında çalışır.
// Use Coil to create and display a thumbnail of a video or image with a specific height
// ImageLoader has its own memory and storage cache, and this one is configured to also
// load frames from videos
val videoEnabledLoader = ImageLoader.Builder(context)
.components {
add(VideoFrameDecoder.Factory())
}.build()
// Coil requests images that match the size of the AsyncImage composable, but this allows
// for precise control of the height
val request = ImageRequest.Builder(context)
.data(mediaUri)
.size(Int.MAX_VALUE, THUMBNAIL_HEIGHT)
.build()
AsyncImage(
model = request,
imageLoader = videoEnabledLoader,
modifier = Modifier
.clip(RoundedCornerShape(20)) ,
contentDescription = null
)
Mümkünse sunucu tarafında küçük resimler oluşturun. Oluştur'u kullanarak resimlerin nasıl yükleneceğiyle ilgili ayrıntılar için Resim yükleme bölümüne, büyük resimlerle nasıl çalışacağınızla ilgili rehberlik için Büyük bitmap'leri verimli bir şekilde yükleme bölümüne bakın.
Yerel resim dosyasından küçük resim oluşturma
Küçük resimler elde etmek, görsel kalitesini korurken etkili bir şekilde ölçek küçültme, aşırı bellek kullanımından kaçınma, çeşitli resim biçimleriyle çalışma ve Exif verilerini doğru şekilde kullanma işlemlerini içerir.
createImageThumbnail yöntemi bunların tümünü yapar ve
resim dosyasının yoluna erişme olanağı sunar.
val bitmap = ThumbnailUtils.createImageThumbnail(File(file_path), Size(640, 480), null)
Yalnızca Uri kullanıyorsanız loadThumbnail yöntemini şurada kullanabilirsiniz:
İçerik Çözücü aracı, Android 10, API düzeyi 29 sürümünden itibaren kullanılabilir.
val thumbnail: Bitmap =
applicationContext.contentResolver.loadThumbnail(
content-uri, Size(640, 480), null)
Android 9, API düzeyi 28'den itibaren sunulan ImageDecoder'da ise bazı özellikler kod çözerken resmin yeniden örneklenmesi için sabit seçenekler sunar. pek de iyi olmadığını unutmayın.
class DecodeResampler(val size: Size, val signal: CancellationSignal?) : OnHeaderDecodedListener {
private val size: Size
override fun onHeaderDecoded(decoder: ImageDecoder, info: ImageInfo, source:
// sample down if needed.
val widthSample = info.size.width / size.width
val heightSample = info.size.height / size.height
val sample = min(widthSample, heightSample)
if (sample > 1) {
decoder.setTargetSampleSize(sample)
}
}
}
val resampler = DecoderResampler(size, null)
val source = ImageDecoder.createSource(context.contentResolver, imageUri)
val bitmap = ImageDecoder.decodeBitmap(source, resampler);
Erken hedefleyen uygulamalar için küçük resimler oluşturmak üzere BitmapFactory'yi kullanabilirsiniz Android sürümleri BitmapFactory.Options, yeniden örnekleme amacıyla yalnızca bir resmin sınırlarının kodunu çözen bir ayar içerir.
Öncelikle, bitmap'in yalnızca sınırlarını BitmapFactory.Options içine kodlayın:
private fun decodeResizedBitmap(context: Context, uri: Uri, size: Size): Bitmap?{
val boundsStream = context.contentResolver.openInputStream(uri)
val options = BitmapFactory.Options()
options.inJustDecodeBounds = true
BitmapFactory.decodeStream(boundsStream, null, options)
boundsStream?.close()
Örneği ayarlamak için BitmapFactory.Options içindeki width ve height öğelerini kullanın
boyut:
if ( options.outHeight != 0 ) {
// we've got bounds
val widthSample = options.outWidth / size.width
val heightSample = options.outHeight / size.height
val sample = min(widthSample, heightSample)
if (sample > 1) {
options.inSampleSize = sample
}
}
Akışın kodunu çözün. Ortaya çıkan görüntünün boyutu, iki kuvvet ile örneklenir
(inSampleSize) daha önemlidir.
options.inJustDecodeBounds = false
val decodeStream = context.contentResolver.openInputStream(uri)
val bitmap = BitmapFactory.decodeStream(decodeStream, null, options)
decodeStream?.close()
return bitmap
}
Yerel video dosyasından küçük resim oluşturma
Video küçük resimlerini taşımanın zorluklarının birçoğu, ancak dosya boyutları çok daha büyük olabiliyor ve daha temsili video karesi her zaman ilk kareyi seçmek kadar kolay olmayabilir. belirir.
Video dosyasının yoluna erişiminiz varsa createVideoThumbnail yöntemi iyi bir seçimdir.
val bitmap = ThumbnailUtils.createVideoThumbnail(File(file_path), Size(640, 480), null)
Yalnızca bir içerik URI'sına erişebiliyorsanız
MediaMetadataRetriever.
Öncelikle videonun yerleşik bir küçük resmi olup olmadığını kontrol edin ve mümkün:
private suspend fun getVideoThumbnailFromMediaMetadataRetriever(context: Context, uri: Uri, size: Size): Bitmap? {
val mediaMetadataRetriever = MediaMetadataRetriever()
mediaMetadataRetriever.setDataSource(context, uri)
val thumbnailBytes = mediaMetadataRetriever.embeddedPicture
val resizer = Resizer(size, null)
ImageDecoder.createSource(context.contentResolver, uri)
// use a built-in thumbnail if the media file has it
thumbnailBytes?.let {
return ImageDecoder.decodeBitmap(ImageDecoder.createSource(it));
}
Videonun MediaMetadataRetriever genişliği ve yüksekliğini al ve
ölçeklendirme faktörünü hesaplayın:
val width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)
?.toFloat() ?: size.width.toFloat()
val height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)
?.toFloat() ?: size.height.toFloat()
val widthRatio = size.width.toFloat() / width
val heightRatio = size.height.toFloat() / height
val ratio = max(widthRatio, heightRatio)
Android 9 ve sonraki sürümlerde (API düzeyi 28) MediaMetadataRetriever, ölçeklendirilmiş
çerçeve:
if (ratio > 1) {
val requestedWidth = width * ratio
val requestedHeight = height * ratio
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val frame = mediaMetadataRetriever.getScaledFrameAtTime(
-1, OPTION_PREVIOUS_SYNC,
requestedWidth.toInt(), requestedHeight.toInt())
mediaMetadataRetriever.close()
return frame
}
}
Aksi takdirde, ilk kareyi ölçeklenmemiş olarak döndürün:
// consider scaling this after the fact
val frame = mediaMetadataRetriever.frameAtTime
mediaMetadataRetriever.close()
return frame
}