Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
よしなに頑張る画像ロードの話 / image load mettya tsurai
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Yoshihiro WADA
June 18, 2019
Programming
550
2
Share
よしなに頑張る画像ロードの話 / image load mettya tsurai
2019/06/18に開催されたPotatotips #62にて発表したスライドです
Yoshihiro WADA
June 18, 2019
More Decks by Yoshihiro WADA
See All by Yoshihiro WADA
AndroidデバイスにFTPサーバを建立する
e10dokup
0
1.2k
Gradleの実行環境設定を見直す
e10dokup
0
1.3k
Firebase App Distributionのテストアプリ配信を試しやすくする
e10dokup
1
720
アプリに署名する 〜GitHub ActionsでのCIも見据えて〜
e10dokup
0
1.3k
Profileable buildでより正確なパフォーマンスを掴む
e10dokup
0
790
[DroidKaigi 2021] メディアアクセス古今東西 / Now and Future of Media Access
e10dokup
0
3.9k
今更「dp」を考える / Let's think about "dp" now
e10dokup
0
5.9k
1から学ぶAndroidアプリデバッグ - アプリの動作を追いかけよう / Learn Android application debugging from the scratch - track apps' behaviors
e10dokup
10
3.6k
Guide to background processingを読んでみる / Reading "Guide to background processing"
e10dokup
0
300
Other Decks in Programming
See All in Programming
(Re)make Regexp in Ruby: Democratizing internals for the JIT
makenowjust
3
1k
ハーネスエンジニアリングにどう向き合うか 〜ルールファイルを超えて開発プロセスを設計する〜 / How to approach harness engineering
rkaga
28
19k
AI時代だからこそ「Bloc」を採用する価値があるのかもしれない
takuroabe
0
110
空間オーディオの活用
objectiveaudio
0
140
How We Benchmarked Quarkus: Patterns and anti-patterns
hollycummins
1
180
PHPer、Cloudflare に引っ越す
suguruooki
1
140
アクセシビリティ試験の"その後"を仕組み化する
yuuumiravy
1
200
20260514_its_the_context_window_stupid.pdf
heita
0
810
認証統合から始めるフロントエンドの機能単位開発 — マイクロサービス思想の適用
koukimiura
0
100
cloudnative conference 2026 flyle
azihsoyn
0
150
実践ハーネスエンジニアリング:ステアリングループを実例から読み解く / Practical Harness Engineering: Understanding Steering Loops Through Real-World Examples
nrslib
5
4.8k
【26新卒研修資料】TDD実装演習
dip_tech
PRO
0
180
Featured
See All Featured
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.7k
Raft: Consensus for Rubyists
vanstee
141
7.4k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
Practical Orchestrator
shlominoach
191
11k
So, you think you're a good person
axbom
PRO
2
2k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
180
Navigating Weather and Climate Data
rabernat
0
190
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
340
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Context Engineering - Making Every Token Count
addyosmani
9
870
What's in a price? How to price your products and services
michaelherold
247
13k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
2
1k
Transcript
Yoshihiro Wada a.k.a. @e10dokup Potatotips #62 - 2019/06/18
Yoshihiro Wada a.k.a. @e10dokup CyberAgant Inc. / Ameba Ameba
None
1 URL 2 3 3.5
bumptech/glide square/picasso Image Loading Library bumptech/glide 4.9.0 ConstraintLayout
1 URL
GlideApp.with(this) .load(/* Image URL */) .placeholder(/* Placeholder Drawable */) .error(/*
Error Drawable */) .into(/* Target ImageView */)
2
ConstraintLayout XML ImageView <ImageView android:id=“@+id/image_view” android:layout_width="0dp" android:layout_height=“0dp” app:layout_constraintDimensionRatio="H,3:2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf=“parent" />
centerCrop GlideApp.with(this) .load(/* Image URL */) .placeholder(/* Placeholder Drawable */)
.error(/* Error Drawable */) .centerCrop() .into(/* Target ImageView */)
XML BindingAdapter <ImageView android:id=“@+id/image_view” android:layout_width="0dp" android:layout_height=“0dp” app:layout_constraintDimensionRatio="H,3:2" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf=“parent”
app:url=“@{imageUrl}” />
BindingAdapter BindingAdapter @BindingAdapter(“url") internal fun ImageView.loadImage(url: String?) { if (url
== null) { setImageDrawable(null) return } GlideApp .with(this) .load(url) .centerCrop() .into(this) }
3
DimensionRatio
API URL BindingAdapter DimensionRatio 3 <ImageView android:id=“@+id/image_view” android:layout_width="0dp" android:layout_height=“0dp” app:width=“@{imageWidth}”
app:height=“@{imageHeight}” app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf=“parent” app:url=“@{imageUrl}” />
width/height dimensionRatio BindingAdapter layout_constraintDimensionRatio ConstraintLayout BindingAdapter 3 @BindingAdapter(“width”, “height”) internal
fun ImageView.setAspectRatio(width: Int, height: Int) { (layoutParams as ConstraintLayout.LayoutParams).dimensionRatio = “h,${width}:${height}” }
glide RequestListener Drawable requestLayout() onMeasure() 3.5
3.5 override fun onResourceReady( resource: Drawable?, model: Any?, target: Target<Drawable>?,
dataSource: DataSource?, isFirstResource: Boolean ): Boolean { resource ?: return false val width = resource.intrinsicWidth.toFloat() val height = resource.intrinsicHeight.toFloat() aspectRatio = width / height requestLayout() return false }
3.5 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { aspectRatio?.let {
// ݱঢ়ͷԣ෯Λऔಘ͠ɺ৽نʹΞεϖΫτൺΛөͨ͠αΠζʹΓସ͑Δ val width = MeasureSpec.getSize(widthMeasureSpec) val w = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY) val h = MeasureSpec .makeMeasureSpec((width / it).toInt(), MeasureSpec.EXACTLY) super.onMeasure(w, h) return } super.onMeasure(widthMeasureSpec, heightMeasureSpec) }
4
*NBHF7JFX *NBHF7JFX *NBHF7JFX
Load Bitmap Glide CenterCrop() Transformation Transformation 4:2 2 ->
-> Transformation
• override fun updateDiskCacheKey(messageDigest: MessageDigest) equals() / hashCode() • override
fun transform( pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int ): Bitmap toTransform Bitmap BitmapTransformation
override fun transform( pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight:
Int ): Bitmap { val width = toTransform.width val height = toTransform.height aspectRatio = width / height return when { aspectRatio >= 2 -> // 2:5 ΑΓԣ cropWidth(pool, toTransform, imageWidth, imageHeight) else -> // ͦΕҎ֎ͷͱ͖ɺͦͷ··BitmapΛฦ٫ toTransform } }
private fun transform( pool: BitmapPool, toTransform: Bitmap, width: Int, height:
Int ): Bitmap { val croppedWidth = (width * 0.5).toInt() return TransformationUtils.centerCrop( pool, toTransform, trimmedWidth, height ) }
None
:pray: