前提・実現したいこと
現在android studioでポケモン図鑑を作ろうとしています。
ImageViewに画像を載せるとき、自動的に画像がImageViewの大きさに合わせて拡縮されますよね?そこで、ゲームで使われるドット絵のように縦横の画素数が極めて少ない画像を画面いっぱいに表示しようとするとぼやけてしまいます。これをぼやけないようにしたいです。
発生している問題・エラーメッセージ
該当のソースコード
MainActivity
Kotlin
1package com.example.myapplication 2 3import android.graphics.Bitmap 4import android.graphics.BitmapFactory 5import android.support.v7.app.AppCompatActivity 6import android.os.Bundle 7import android.os.Environment 8import android.widget.ImageView 9import com.bumptech.glide.Glide 10import kotlin.math.min 11 12class MainActivity : AppCompatActivity() { 13 14 override fun onCreate(savedInstanceState: Bundle?) { 15 super.onCreate(savedInstanceState) 16 setContentView(R.layout.activity_main) 17 val view = findViewById<ImageView>(R.id.imageView) 18 19 //pngの場合 20 view.setImageBitmap( 21 BitmapFactory.decodeFile( 22 Environment.getExternalStorageDirectory().path + "/MyApp/pikachu_static.png" 23 ) 24 ) 25 26 //gifの場合 27 Glide 28 .with(this) 29 .load( 30 Environment.getExternalStorageDirectory().path + "/MyApp/pikachu_dynamic.gif" 31 ) 32 .into(view) 33 } 34}
activity_main
XML
1<?xml version="1.0" encoding="utf-8"?> 2<android.support.constraint.ConstraintLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 xmlns:app="http://schemas.android.com/apk/res-auto" 6 android:layout_width="match_parent" 7 android:layout_height="match_parent" 8 tools:context=".MainActivity"> 9 10 <ImageView 11 android:layout_width="0dp" 12 android:layout_height="0dp" 13 tools:srcCompat="@tools:sample/avatars" 14 android:id="@+id/imageView" 15 app:layout_constraintStart_toStartOf="parent" 16 app:layout_constraintEnd_toEndOf="parent" 17 app:layout_constraintTop_toTopOf="parent" 18 app:layout_constraintBottom_toBottomOf="parent" 19 android:layout_marginTop="24dp" 20 android:layout_marginStart="24dp" 21 android:layout_marginEnd="24dp" 22 android:layout_marginBottom="24dp"/> 23</android.support.constraint.ConstraintLayout>
試したこと
- Vector Drawableにする
→ベクタ画像にしたことでぼやけは完全になくなったが、gifには使えない。
- あらかじめ縦横の画素数を何倍かに増やしておく
→ファイルサイズが大きくなるうえ、何倍に拡大すれば目立たなくなる程度のぼやけになるのかも決定できない。あまりスマートでないのでやりたくない。
- Bitmap.createScaledBitmap()を使って動的に拡大したものを表示する
→静止画はきれいに表示できる。しかしGlideを使ってgifを表示するときは使えない。
Main Activity
kotin
1package com.example.myapplication 2 3import android.graphics.Bitmap 4import android.graphics.BitmapFactory 5import android.os.Bundle 6import android.os.Environment 7import android.support.v7.app.AppCompatActivity 8import android.view.ViewTreeObserver 9import android.widget.ImageView 10import kotlin.math.min 11 12class MainActivity : AppCompatActivity() { 13 14 override fun onCreate(savedInstanceState: Bundle?) { 15 super.onCreate(savedInstanceState) 16 setContentView(R.layout.activity_main) 17 val view = findViewById<ImageView>(R.id.imageView) 18 19 view.viewTreeObserver.addOnGlobalLayoutListener( 20 object : ViewTreeObserver.OnGlobalLayoutListener { 21 override fun onGlobalLayout() { 22 //getResizedBitmap()はviewの幅と高さが決定してからでないと使えないためここで画像をセットする 23 view.setImageBitmap( 24 getResizedBitmap( 25 BitmapFactory.decodeFile( 26 Environment.getExternalStorageDirectory().path + "/MyApp/pikachu_static.png" 27 ), 28 view 29 ) 30 ) 31 //幅と高さだけ取得できれば用済みなのでリスナを削除 32 view.viewTreeObserver.removeOnGlobalLayoutListener(this) 33 } 34 } 35 ) 36 } 37 38 //originalをviewに入る最大の大きさに拡大する。このときcreateScaledBitmap()のfilterにfalseを指定するとぼやけないっぽい。 39 fun getResizedBitmap(original: Bitmap, view: ImageView): Bitmap { 40 val magnification = min(view.width / original.width, view.height / original.height) 41 return Bitmap.createScaledBitmap( 42 original, original.width * magnification, original.height * magnification, false 43 ) 44 } 45}
activity_main
さっきと一緒
補足情報(FW/ツールのバージョンなど)
android studioのバージョンは3.3、使用した実機及びエミュレータのOSは8.0、APIレベルは26です。
上にのせたサンプルコードで使っている画像はこの二つです。
自動的にImageViewの大きさに合わせて画像が拡縮されるということはないと思います。画像ファイルはどのディレクトリに入れていますか?
画像ファイルは、掲載したソースコードの方ではリソースから読み込んでいましたが実際に作ったアプリの方ではストレージから読み込んでいます(掲載しているほうのソースコードもそれに合わせ一部修正しました)。
また画像の拡縮に関してですが、ImageViewは掲載したXMLに書かれているように「上下左右24dpのマージンを確保しつつ画面いっぱいに広げる」といったものになっています。先ほどこのマージンを大きくすることでImageViewが小さくなるようにし、画像がどのように表示されるのか確かめてみたのですがやはり画像の方もImageView同様小さくなっていました。なので「自動的にImageViewの大きさに合わせて画像が拡縮される」ということに間違いはなさそうなのですが...
画像がImageViewのサイズよりも小さく描画されることを期待しているということでしょうか?それならばImageViewのScaleTypeを調整することによりそのような挙動になるはずです。
あくまでImageViewのサイズに合わせつつ描画時にボケないようにする方法については、回答に書きますね。

回答2件
あなたの回答
tips
プレビュー