android SDカードの画像を背景にタイル表示する

画像を背景にタイル表示する方法は前XMLファイルを使用した方法を試したのですが、これだと画像が固定されてしまいます。
画像を変えたければアプリを作り直すしかないわけで、汎用性がありません。
SDカードに入っている画像を自由に設定する方法を探してみました。


Eclipseを使用しました。android 2.2(APIレベル8)です。





コードは以下の通りです。
ボタンを押すと背景が指定画像のタイリング表示と拡大表示とに交互に切り替わります。
画像はSDカードに置くわけですが、エミュにデータを転送するのが面倒だったので、起動時にアイコン画像をSDカードに コピーするコードを組み込みました。エミュにいろいろデータを置いている方は上書きされないようにご注意ください。
ちなみにディレクトリ「/mnt/sdcard/」にファイル名「TileMode.png」で保存されます。
SDカードに書込を行うためにマニフェストファイルの変更も必要です。(赤で表示した1行を追加します)



main.xml layoutに置きます
背景画像を表示するためにImageViewを用意します。FrameLayoutに配置してLinearLayoutと重なるように表示します。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">
   <ImageView
      android:id="@+id/imageView1"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:scaleType="center"
   />

   <LinearLayout
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical" >

      <Button
         android:id="@+id/button1"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="Button" />


   </LinearLayout>

</FrameLayout>




AndroidManifest.xml
SDカードに書込を行うために赤で表示した1行を追加します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="tile.mode.namespace"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".TileModeActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
</manifest>





TileModeActivity.java

package tile.mode.namespace;

import java.io.File;
import java.io.FileOutputStream;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

public class TileModeActivity extends Activity {

	Button button1;
	boolean btyp=true;
	String path1;
	ImageView imageView1;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        saveBitmapToSd();//SDカードに画像ファイルをコピー
        
        imageView1 = (ImageView)findViewById(R.id.imageView1);
        imageView1.setBackgroundColor(Color.BLUE);
    	path1 = Environment.getExternalStorageDirectory().getPath()+"/TileMode.png";
    	button1=(Button)findViewById(R.id.button1);
    	button1.setOnClickListener(new OnClickListener(){
			public void onClick(View arg0) {
				if(btyp){//タイル表示
			    	try{
			    	    BitmapDrawable bmpDrawer =(BitmapDrawable) Drawable.createFromPath(path1);
			            bmpDrawer.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
			            imageView1.setBackgroundDrawable(bmpDrawer);
				    imageView1.setImageBitmap(null);
			    	}
			    	catch(Exception e){Log.d("Error",e.toString());}
					
				}
				else{//拡大表示
			    	try{
			            imageView1.setScaleType(ScaleType.CENTER_CROP);
			            Bitmap bitmap = BitmapFactory.decodeFile(path1);
				    imageView1.setImageBitmap(bitmap);
			            imageView1.setBackgroundDrawable(null);
			    	}
			    	catch(Exception e){Log.d("Error",e.toString());}
					
				}
				btyp=!btyp;
			}});
    }

	//使用する画像をSDカードに保存する
	public void saveBitmapToSd() {
		try {
	        PackageManager pm = getPackageManager(); 
	        ResolveInfo appData=pm.resolveActivity(getIntent(), 0);
	        Drawable appIcon = appData.loadIcon(pm);
	        
	        Bitmap mBitmap=((BitmapDrawable) appIcon).getBitmap();
	        // sdcardフォルダを指定
	        File root = Environment.getExternalStorageDirectory();
	        // 保存処理開始
	        FileOutputStream fos = null;
	        fos = new FileOutputStream(new File(root, "TileMode.png"));
	        // PNGで保存
	        mBitmap.compress(CompressFormat.PNG, 100, fos);
	        // 保存処理終了
	        fos.close();
		} catch (Exception e) {
		Log.e("Error", "" + e.toString());
		}
	}
	
}




【おまけ】
タイル表示の時にはsetBackgroundDrawable、拡大表示の時にはsetImageBitmapを使うというコードになってしまいました。
setBackgroundDrawableでもsetTileModeXYを外せば拡大表示になるのですが、ScaleTypeが選べないのでこのようにしました。
なにか方法があるのかもしれません。


【参考】
[Android] 外部ストレージに配置した複数の画像を状態付きで設定する
Bitmap画像をsdに保存



TOPに戻る
2012/5/4