1. 程式人生 > >使用BitmapShader實現簡單繪圖

使用BitmapShader實現簡單繪圖

MainActivity中的程式碼:

package com.example.drawbitmap;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.Style;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;


public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ImageView iv = (ImageView) this.findViewById(R.id.iv);
        Bitmap bitmap = createBitmap();
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        //設定繪製文字的時候,文字大小
        paint.setTextSize(50);
        paint.setStyle(Style.FILL);
        
        paint.setStrokeWidth(30);
        
        /*
         * 使用純色填充的時候,setColor設定要填充的顏色
         * 如果想使用漸變色,需要使用Shader
         * 如果設定了shader,則使用shader
         * */
        Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        /**
         * 引數1: bitmapshader要使用的圖片
         * 引數2: x填充型別
         * 引數3: y方向填充型別
         */
        Shader shader = new BitmapShader(icon, TileMode.REPEAT, TileMode.MIRROR);
        paint.setShader(shader);
        
//        new LinearGradient(0, 0, 100, 0, Color.BLUE, Color.RED, TileMode.REPEAT)
        //設定繪製顏色
        paint.setColor(0xffff0000);//如果純色填充的時候,使用的顏色
        
        //用純色填充畫布
        canvas.drawColor(0xFFAAAAAA);
        canvas.drawText("hehehe", 100, 100, paint);
        canvas.drawRect(50, 50, 350, 150, paint);
        
        iv.setImageBitmap(bitmap);
        
        canvas.drawLine(0, 0, 400, 400, paint);
    }
    
    private Bitmap createBitmap()
    {
    	Bitmap bitmap = Bitmap.createBitmap(400, 400, Config.ARGB_8888);
    	
    	return bitmap;
    }
}

SecondActivity中程式碼:(作為啟動介面)

package com.example.drawbitmap;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Shader.TileMode;
import android.net.Uri;
import android.net.Uri.Builder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.Toast;

public class SecondActivity extends Activity{

	private Canvas canvas;
	private Paint paint;
	private ImageView iv;
	private Bitmap bitmap;
	private BitmapShader shader;
	public static final int BG_COLOR = 0xffaaaaaa;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.activity_main);
		
		iv = (ImageView) this.findViewById(R.id.iv);
		bitmap = createBitmap();
		
		Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.start);
		shader = new BitmapShader(b, TileMode.REPEAT, TileMode.REPEAT);
		
		canvas = new Canvas(bitmap);
		paint = new Paint();
		canvas.drawColor(BG_COLOR);
		iv.setImageBitmap(bitmap);
		iv.setOnTouchListener(touchListener);
	}
	
	
	OnTouchListener touchListener = new OnTouchListener()
	{
		float startX = 0;//用來緩衝起始位置x
		float startY = 0;//用來緩衝起始位置y
		
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				startX = event.getX();
				startY = event.getY();
				break;
				
			case MotionEvent.ACTION_MOVE:
				float stopX = event.getX();
				float stopY = event.getY();
				canvas.drawLine(startX, startY, stopX, stopY, paint);
				iv.setImageBitmap(bitmap);
				//這次的終止位置作為下次的起始位置儲存
				startX = stopX;
				startY = stopY;
				break;
			case MotionEvent.ACTION_UP:
				break;
			default:
				break;
			}
			return true;
		}
	};
	
	private Bitmap createBitmap()
    {
    	Bitmap bitmap = Bitmap.createBitmap(400, 400, Config.ARGB_8888);
    	
    	return bitmap;
    }
	
	public void red(View view)
	{
		paint.setColor(0xffff0000);
	}
	
	public void green(View view)
	{
		paint.setColor(0xff00ff00);
	}
	public void blue(View view)
	{
		paint.setColor(0xff0000ff);
	}
	
	public void erase(View view)
	{
		paint.setShader(null);
		paint.setColor(BG_COLOR);
	}
	
	public void big(View view)
	{
		paint.setStrokeWidth(paint.getStrokeWidth() + 3);
	}
	
	public void small(View view)
	{
		float width = paint.getStrokeWidth() - 3;
		if(width < 1)
		{
			width = 1;
		}
		paint.setStrokeWidth(width);
	}
	
	public void installShader(View view)
	{
		//設定shader
		paint.setShader(shader);
	}
	
	public void uninstallShader(View view)
	{
		//取消shader
		paint.setShader(null);
	}
	
	public void save(View view)
	{
		String dirName = Environment.getExternalStorageDirectory() + "/我的大作/";
		new File(dirName).mkdirs();
		
		File file = new File(dirName,System.currentTimeMillis()+".jpg");
		FileOutputStream outputStream = null;
		try {
			outputStream = new FileOutputStream(file);
			bitmap.compress(CompressFormat.JPEG, 75, outputStream);
			Toast.makeText(this, "圖片儲存到了: " + file.getAbsolutePath() , Toast.LENGTH_LONG).show();
			Log.e("", file.getAbsolutePath());
			
			Intent i = new Intent();
			i.setAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);//設定通知系統掃描sd卡上檔案的action
			//這個廣播需要攜帶一個檔案的資料
//			Uri uri = Uri.parse("file://" + file.getAbsolutePath());//手動拼接uri的路徑
			
			Uri uri = Uri.fromFile(file);//呼叫api,把一個file檔案生成uri
			i.setData(uri);
			sendBroadcast(i);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}finally{
			if(outputStream != null)
			{
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		//把記憶體裡的內容壓縮到一個輸出流裡
	}
}


在layout中作為顯示的xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.drawbitmap.MainActivity" >

    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
	
    <LinearLayout android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        
         <Button 
	        android:layout_height="wrap_content"
	        android:text="紅色"
	        android:onClick="red"
	        android:textColor="#ff0000"
	        style="@style/btn_paint"
	        />
         
         <Button 
	        android:layout_height="wrap_content"
	        style="@style/btn_paint"
	        android:text="綠色"
	        android:onClick="green"
	        android:textColor="#00ff00"
	        />
         
         <Button 
	        android:layout_height="wrap_content"
	        style="@style/btn_paint"
	        android:text="藍色"
	        android:textColor="#0000ff"
	        android:onClick="blue"
	        />
         
         <Button 
	        android:layout_height="wrap_content"
	        style="@style/btn_paint"
	        android:text="擦除"
	        android:onClick="erase"
	        />
         
    </LinearLayout>
    
    <RelativeLayout android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
       >
        
         <Button 
	        android:layout_height="wrap_content"
	        android:layout_width="wrap_content"
	        android:text="變粗"
	        android:onClick="big"
	        android:layout_marginLeft="20dp"
	        />
         
         <Button 
	        android:layout_height="wrap_content"
	        android:layout_width="wrap_content"
	        android:text="變細"
	        android:onClick="small"
	        android:layout_centerHorizontal="true"
	        />
         
    </RelativeLayout>
    
    <RelativeLayout android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        
         <Button 
	        android:layout_height="wrap_content"
	        android:layout_width="wrap_content"
	        android:text="使用shader"
	        android:onClick="installShader"
	        android:layout_marginLeft="20dp"
	        />
         
         <Button 
	        android:layout_height="wrap_content"
	        android:layout_width="wrap_content"
	        android:text="取消shader"
	        android:onClick="uninstallShader"
	        android:layout_alignParentRight="true"
	        android:layout_marginRight="20dp"
	        />
         
    </RelativeLayout>
   
    <Button 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="儲存"
        android:onClick="save"
        android:layout_gravity="center_horizontal"
       />
</LinearLayout>


配置清單檔案:(Sdcard卡讀寫權,與設定SecondActivity做為啟動介面)

<!-- 配置應用對SD卡的讀寫權 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
        </activity>
        
        <activity android:name="com.example.drawbitmap.SecondActivity">
             <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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