ImgeViewで画面に表示させるときに、元画像のサイズ(縦横)が大きいと表示しきれない事があります。このPicassoを使うと簡単に表示できます。
2021.1.1
Picasso
Picassoは画像をネットからダウンロードしたり、ギャラリーなどでのキャッシュなど、いい具合に画像を扱ってくれます。
大きいdrawableの画像を取り込む
例えばこのような 5760×3760 サイズの画像をImageViewで表示させてみます。
画像をres\drawable\に入れて、
1 2 3 4 |
ImageView imageView = findViewById(R.id.image_view); int imgId = R.drawable.img5760x3760; imageView.setImageResource(imgId); |
レイアウト
1 2 3 4 5 6 7 8 9 10 11 12 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/image_view" android:contentDescription="@string/app_name" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> |
これをNexus5Xで試してみると
1 |
java.lang.RuntimeException: Canvas: trying to draw too large(598026240bytes) bitmap. |
というエラーになりました。画像が大きいということです。
Pixel 3aではエラーにはなりませんでしたがワーニングが出ます。
因みに、Nexus5Xでは画像を1/4のimg1440x942では表示できました。
Androidはハイエンドからローエンドまで様々な機種があるので
機種によるパフォーマンス性能の違いは留意する必要があります。
Picassoで大きい画像を取り込む
これをPicassoで試してみます。
dependencyを設定します。バージョンはこちらで、Picasso にて確認して適宜合わせてください。(新しいバージョンが出ているのですがエラーになる場合もあります)
build.gradle
1 2 3 4 5 6 7 8 9 10 |
... android { ... } dependencies { ... implementation 'com.squareup.picasso:picasso:2.5.2' } |
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
package your.package.name; /* Copyright 2013 Square, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ import android.app.Activity; import android.os.Bundle; import android.widget.ImageView; import com.squareup.picasso.Picasso; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ImageView imageView = findViewById(R.id.image_view); int imgId = R.drawable.img5760x3760; // drawable Picasso.with(this) .load(imgId) .fit() .centerInside() .rotate(-270.0f) // landscape .into(imageView); // Assets // Picasso.with(getApplicationContext()) // .load("file:///android_asset/img5760x3760.jpg") // .fit() // .centerInside() // .rotate(-270.0f) // landscape // .into(imageView); // Download // Picasso.with(getApplicationContext()) // .load("https://hoge-hoge.com/images/img5760x3760.jpg") // .fit() // .centerInside() // .rotate(-270.0f) // landscape // .into(imageView); } } |
レイアウト
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/image_view" android:contentDescription="@string/app_name" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> |
これで実行すると、画像が表示されました。
画像が横向きなのでlandscapeにするため回転させています。
assetsから取り込む
drawableから画像を取り込みましたが、assetsからも可能です。画像がたくさんある場合にフォルダー分けできるのでassetsが便利なのですが、try-cathを使ったりとちょっと面倒です。
Picassoではdrawableと同様にできます。assetsは「file:///android_asset/」からのパスで画像を指定すればいいだけです
1 2 3 4 5 6 7 |
// assetsから取得 Picasso.with(getApplicationContext()) .load("file:///android_asset/img5760x3760.jpg") .fit() .centerInside() .rotate(-270.0f) // landscape .into(imageView); |
画像をダウンロード
画像をダウンロードする場合は非同期処理で実行しないといけないので、意外とコードも増えてしまいます。
Picassoでは、これも画像のURLを指定すればダウンロードできてしまいます。
例として https://hoge-hoge.com/image/ 以下に画像を置いて試してみます。
1 2 3 4 5 6 |
Picasso.with(getApplicationContext()) .load("https://hoge-hogege.com/images/img5760x3760.jpg") .fit() .centerInside() .rotate(-270.0f) // landscape .into(imageView); |
ただし、Manifestの記述は必要です。
AndroidManifest.xml
1 2 3 4 5 6 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" ... <uses-permission android:name="android.permission.INTERNET" /> ... </manifest> |
Picasso設定Option
Picassoの設定はこの他にも色々あります。
1 2 3 4 5 6 7 8 9 |
Picasso.with(this) .load(imgId) .fit() //.resize(int pixWidth, int pixHeight) //.resizeDimen(R.dimen.targetWidthResId, R.dimen.targetHeightResId) .centerInside() //.centerCrop() //.rotate(float degrees) .into(imageView); |
- fit()
- レイアウト側で指定したサイズにフィットするサイズです
- この設定でwrap_contentにすると何も表示されなくなります
- resize(int pixWidth, int pixHeight)
- pixelでの設定サイズになります。fitとは同時に使えません
- resizeDimen(R.dimen.targetWidthResId, R.dimen.targetHeightResId)
- dpでのサイズ設定ができますが、res\dimenの設定値を使います
- centerInside()
- 指定サイズ内に収まるように表示されます
- centerCrop()
- 指定サイズを超える場合は画像を切り捨てて表示
- rotate(float degrees)
- 画像の回転
このPicassoはこの他にも画像ダウンロードに使えるので非同期でhttp接続などもやってくれます。
また、ギャラリー・フォトなどGridViewのメモリの問題は頭を悩ませるのですが、これもPicassoが使えます。
References:
Picasso
LruCache