Androidでスケーリングされた階層化された画像をズームする
-
26-10-2019 - |
質問
私が抱えている多くの問題があり、すべて関連しています。私が解決したものもありますが、私が見つけた解決策は、最終製品から私を止めることかもしれません。これは多くの人々が出くわすかなり一般的な問題になると確信しているので、ここですべての問題と解決策について言及します。
最終的な結果私は、上に3つのレイヤー(透明なPNG)があるベース画像を持っています。表示するレイヤーはユーザー次第です。各レイヤーは、より多くの情報をベース画像に追加します。私の状況では、ベースイメージは星の画像です。ユーザーが追加のレイヤーを追加すると、星座の境界、スター名、グリッドが表示されます。また、ユーザーは、空のセクションのより明確な画像のためにエリアにズームインできる必要があります。
最初の問題画像サイズは2つの大きな(1324×1872)で、OutFmemoryエラーが発生します。
使用して画像をスケーリングすることで解決します
/**
* This method scales an image in the assets directory and returns a
* BitmapDrawable object that can be passed to an images setImageBitmap or a
* views setBackgroundDrawable by passing this method into the constructor
* of BitmapDrawable.
* eg ViewGroup.setBackgroundDrawable(
* new BitmapDrawable(getScaledBitMap(this, imagePath, 2)));
*
* @param context
* @param imgFullPath
* @param imageSize
* @return
* @throws IOException
*/
public static Bitmap getScaledBitMap(Context context, String imgFullPath,
int imageSize) throws IOException
{
InputStream instream;
instream = context.getAssets().open(imgFullPath);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = imageSize;
Bitmap bitmap=BitmapFactory.decodeStream(instream, null, options);
return bitmap;
}
このコードは役立ちましたが、3つのレイヤーをロードするときにOutFmemoryエラーが発生します。また、品質が低下するにつれてズームするとき、画像のスケーリングは問題になると思います。
2番目の問題。私が見つけた限り、画像の1つが透明ではない場合、PNGを重ねることはできません。透明な画像は表示されません。透明ではないもののみを表示します(ベース画像)。
これは、FrameLayoutの背景を基本画像に設定し、3つのレイヤーだけを子供としてそのレイアウトに残して解決しました。
3番目の問題は画像をズームインします。ここで解決策になる可能性のあるものを見つけました 画像のズーム機能を取得するにはどうすればよいですか?, 、しかし、エミュレーターにはマルチタッチがなく、私のデバイスが泳ぎに行ったときにそれが好きではなかったため、まだテストしていません。現在、テストする他のデバイスはありません。
OutFmeMoryErrorを取得せずに4つの画像すべて(ベース + 3レイヤー)をロードし、画像をズームする機能を持たせる最良の方法は何ですか。
必要なコードを備えたプロジェクトを作成しました ここ
解決
いくつかの解決策を見つけました。問題1:コードを完了し、見つかったTouchImageViewを使用した後 ここ. 。メモリのエラーがなくなりました。すべてのレイヤーを問題なくロードできます。
2番目と3番目の問題も、TouchImageViewを使用して解決されました。私はそれに満足していますが、クラスがどのように機能し、その理由を解決しようとして多くの時間を費やしたので、クラスがもっとコメントすることを望んでいますが、最終的には失敗しました。
私が抱えていた最後の大きな問題は、ピンチズームが上層層のみをズームするとき(予想どおり)ズームすることでした。これの修正は、TouchImageViewクラスをわずかに変更し、マトリックス変更されたリスナーの機能を追加することでした。マトリックスが変更されると、マトリックスがリスナーに返され、ベース画像を含むすべてのレイヤーのマトリックスが更新されます。これにより、ズームに関係なく、すべての画像がラベルをベース画像の同じ場所を指してズームすると同時にズームします。
これは、リスナーにマトリックスの変更を通知するために使用される非常にシンプルなインターフェイスです
public interface IOnMatixChangedListener
{
public void onMatrixChanged(Matrix matrix);
}