1. 程式人生 > >自定義surfaceview畫圖並儲存Canvas到DCIM

自定義surfaceview畫圖並儲存Canvas到DCIM

自定義surfaceview

package com.app.fantasticbaby;


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Environment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Toast;


/** 
 * @author 作者 E-mail: 
 * @version 建立時間:2016-5-30 下午2:30:59 
 * 類說明 
 */
public class MyView extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener{
    private Paint p = new Paint();
    private Path path = new Path();
    private Bitmap bi  = Bitmap.createBitmap(400, 800, Config.ARGB_8888);
    private SurfaceHolder holder = null;
    private Canvas canvas = null;
    private Canvas canvasTemp = null;
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
holder = getHolder();
holder.addCallback(this);
p.setColor(Color.RED);
p.setTextSize(40);
p.setStrokeWidth(5);
p.setAntiAlias(true);
p.setFlags(Paint.ANTI_ALIAS_FLAG);
p.setStyle(Paint.Style.STROKE);
setOnTouchListener(this);
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub

}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
bi = Bitmap.createBitmap(getWidth(), getHeight(),
               Bitmap.Config.ARGB_8888);
      canvasTemp = new Canvas(bi);
       draw();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub

}


@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
 
            path.moveTo(event.getX(), event.getY());
            draw();
            break;
         //不能將ACTION_DOWN裡的寫在ACTION_MOVE裡,不然會看不到畫出的軌跡
        case MotionEvent.ACTION_MOVE: // 畫出每次移動的軌跡
        case MotionEvent.ACTION_UP:
            path.lineTo(event.getX(), event.getY());
            draw();
            break;
}
return true;
}


private void draw() {
       try {
           canvas = holder.lockCanvas();
           if (holder != null) {
               canvasTemp.drawColor(Color.WHITE);
               canvasTemp.drawPath(path, p);
               canvas.drawBitmap(bi, 0, 0, null);
           }
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           if (holder != null) {
               holder.unlockCanvasAndPost(canvas);
           }
       }
   }
 
  
private String getTime(){
return new SimpleDateFormat("HHmmssSSS").format(new Date(System.currentTimeMillis()));
}
//SurfaceView是不能截圖的,不過看了你程式碼發現不是這個原因造成的儲存不了圖片
//是canvas.setBitmap()的位置不對,畫完才設定Bitmap上去,肯定畫不出來
public void saveCanvas(View v){
//這樣雖然能夠儲存畫出的圖片,但是看不到SurfaceView了
//Canvas c = new Canvas(bi);
//c.drawColor(Color.WHITE);
//this.draw(c);
FileOutputStream fos = null;
String fileName = getTime();
String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+fileName+".png";
try {
fos = new FileOutputStream(new File(filePath));
bi.compress(Bitmap.CompressFormat.PNG, 100, fos);
MediaScannerConnection.scanFile(getContext(), new String[]{filePath}, null, new MediaScannerConnection.OnScanCompletedListener() {

@Override
public void onScanCompleted(String arg0, Uri arg1) {
// TODO Auto-generated method stub
Log.v("MediaScanWork", "file " + arg0
                            + " was scanned seccessfully: " + arg1);
}
});
Toast.makeText(getContext(), "儲存成功,檔名:" + filePath + ".png", Toast.LENGTH_LONG).show();
            clear();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


public void clear() {
// TODO Auto-generated method stub
path.reset();
draw();
}




}

實用activity

package com.app.fantasticbaby;


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


/** 
 * @author 作者 E-mail: 
 * @version 建立時間:2016-5-30 下午3:01:23 
 * 類說明 
 */
public class SurfaceActivity extends Activity {
   private MyView myview;
   private Button btn,save;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.surface_view);
myview = (MyView)findViewById(R.id.draw);
btn = (Button)findViewById(R.id.btn);
save = (Button)findViewById(R.id.save);
btn.setOnClickListener(new OnClickListener(){


@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
 myview.clear();
}

});
save.setOnClickListener(new OnClickListener(){


@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
myview.saveCanvas(myview);
}

});


}
    
}

佈局:

<?xml version="1.0" encoding="UTF-8"?>
<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"
        >
 
 
    <com.app.fantasticbaby.MyView
            android:id="@+id/draw"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            />
 
    <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
 
            >
        <Button
                android:id="@+id/btn"
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="清理"
                />
 
        <Button
                android:id="@+id/save"
                android:layout_weight="1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="儲存"
                />
 
    </LinearLayout>
  
</LinearLayout>

截圖: