2013年11月18日

【Android】ImageViewでクリッカブルマップ的なやつ

画像のクリック位置によって処理を分岐したい事ってありますよね?
AndroidのImageViewを使ってそれを実現する方法です。


クリックした座標を拾って、座標で判断するのも一つの方法ですが
地図画像なんかの場合は、境界がクネクネしているので座標の指定が細かくてやってられません。
ということで、もっとスマートにできないかと悩んだ結果
処理分岐したいエリアで色分けした、クリック用の画像を別に用意して、
クリックされたポイントの色で判断することにしました。

【考え方】
1.ユーザーに見える画像の裏にクリック用の画像を置く
2.クリック位置を判定して、その部分の色を取得
3.あとは色に応じて処理を分岐すれば良い
※画像はFIT_XYでImageViewいっぱいに表示している前提とします



//クリック用画像のタッチリスナー設定
ImageView img = (ImageView) findViewById(R.id.imageForClick);
img.setOnTouchListener(this);


//タッチリスナー
@Override
public boolean onTouch(View v, MotionEvent event) {
float x, y;
x = event.getX();
y = event.getY();


switch(v.getId()){
case R.id.imageForClick:

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//ACTION_UPで判定するならここで処理してもよい
return true;

case MotionEvent.ACTION_UP:
ImageView img = (ImageView)v;

//クリック位置を取得
float[] pos = getImageClickPos(x,y,img);
float posX = pos[0];
float posY = pos[1];

BitmapDrawable drawable = (BitmapDrawable) img.getDrawable();
Bitmap bmp = drawable.getBitmap();

int width = bmp.getWidth();
int height = bmp.getHeight();

int getX = (int) (width * posX / 100);
int getY = (int) (height * posY / 100);

//クリック位置の色を取得
int c = bmp.getPixel(getX, getY);

int r = Color.red(c);
int g = Color.green(c);
int b = Color.blue(c);

//あとは、色に応じて処理を分岐すれば良い

return false;

}
break;
}

return false;
}



//ImageView上の画像クリック位置をパーセント値で返す
float[] getImageClickPos(float clickX, float clickY, ImageView img){

float[] ret = {0,0};

//画像の表示サイズを求める
float[] imgSize = getImageViewPicSize(img);
float imageWidth = imgSize[0];
float imageHeight = imgSize[1];


ret[0] = clickX * 100 / imageWidth;
ret[1] = clickY * 100 / imageHeight;

return ret;

}

//ImageView上の画像の表示サイズを求める
float[] getImageViewPicSize(ImageView img){

float[] ret = {0,0};

Rect rect = img.getDrawable().getBounds();

float scaleX = (float) img.getWidth() / (float) rect.width();
float scaleY = (float) img.getHeight() / (float) rect.height();
float scale = Math.min(scaleX, scaleY);
ret[0] = scale * rect.width();
ret[1] = scale * rect.height();

return ret;
}


タグ:Imageview
posted by pltokyo at 15:26| Comment(0) | Android

2013年11月15日

【Android】元画像の比率を保ったまま画面の横幅いっぱいに表示する

AndroidのImageViewで、オリジナル画像の縦横比を保ったまま画面の横幅いっぱいに表示する方法です。

最初は、ScaleTypeなどのプロパティだけで対応しようとしたのですが、
オリジナル画像を拡大するケースや縮小するケースにすべて対応しようとすると難しかったので、
動的にImageViewのサイズを変えることにしました。

【考え方】
1.ImageViewの幅は画面の横幅とする
2.オリジナル画像の横幅を求める
3.オリジナル画像の横幅と画面の横幅との比率を求める
4.ImageViewの縦幅を上記で求めた比率に従って設定する
5.ScaleTypeにFIT_XYを指定してImageViewいっぱいに表示する


//画像の表示方法を決める
ImageView img = (ImageView) findViewById(R.id.image);

//拡大縮小比率算出
float scale = 【画面の横幅】 / 【オリジナル画像の横幅】;
//表示画像のサイズ比率に応じてimageviewのサイズを調整
int imgX=scale * 【オリジナル画像の横幅】;
int imgY=scale * 【オリジナル画像の縦幅】;

//ImageViewのサイズ変更
img.setLayoutParams(new LinearLayout.LayoutParams(imgX,imgY));
//ImageViewのScaleType変更
img.setScaleType(ImageView.ScaleType.FIT_XY );


※画面サイズ、オリジナル画像のサイズ取得方法については省略します
posted by pltokyo at 17:52| Comment(2) | Android