Problem saving drawing/signature

Problems with Canvas, OpenGL, etc...

Problem saving drawing/signature

Postby stece » Wed Nov 03, 2010 12:30 pm

Dear

I need to implement a part of code which I can't find any tutorial or documentation about the problem. I needed to implement the possibility for clients to draw a signature on an android device and this signature must be saved as an image.

I got the drawing a signature part. But I can't find a way to save this result as an image. Can someone help? I also looked for a public draw/signature intent like the barcode scanner but didn't find anything.

this is the source code from the activity with the signature as it is now:
Code: Select all
package be.xios.servinter;
import java.util.ArrayList;

import be.xios.servinter.utils.MyDate;
import be.xios.servinter.valueObjects.ServiceCommentLine;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

public class Signature extends Activity {

   private final int CODE_SIGNATURE = 2;
   private Paint mPaint;
   private Panel pnlPanel;
   private Button btnClear;
   private Button btnSave;
   private LinearLayout content;
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.signature);
      
      content = (LinearLayout) findViewById(R.id.signaturePanel);
      pnlPanel = new Panel(this);
      pnlPanel.setBackgroundColor(Color.WHITE);
      
      content.addView(pnlPanel, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
      content.setDrawingCacheEnabled(true);
      
      btnClear = (Button) findViewById(R.id.btnSignatureClear);
      btnClear.setOnClickListener(new OnClickListener() {         
         public void onClick(View v) {
            pnlPanel.reDraw();
         }
      });
      
      btnSave = (Button) findViewById(R.id.btnSignatureSave);
      btnSave.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
            Bitmap bmp = content.getDrawingCache();
            AlertDialog.Builder alert = new AlertDialog.Builder(getApplicationContext());
            final ImageView input = new ImageView(getApplicationContext());
            input.setImageBitmap(bmp);
            alert.setView(input);

            alert.setNegativeButton("X",
                  new DialogInterface.OnClickListener() {
                     public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.cancel();
                     }
                  });
            alert.show();
         }
      });
      
      mPaint = new Paint();
      mPaint.setDither(true);
      mPaint.setColor(Color.BLACK);
      mPaint.setStyle(Paint.Style.STROKE);
      mPaint.setStrokeJoin(Paint.Join.ROUND);
      mPaint.setStrokeCap(Paint.Cap.ROUND);
      mPaint.setStrokeWidth(3);
   }

   class Panel extends SurfaceView implements SurfaceHolder.Callback {
      private TutorialThread _thread;
      private ArrayList<Path> _graphics = new ArrayList<Path>();

      private Path path;

      public Panel(Context context) {
         super(context);
         getHolder().addCallback(this);
         _thread = new TutorialThread(getHolder(), this);
         setFocusable(true);
      }

      public void reDraw(){
         _graphics = new ArrayList<Path>();
         setBackgroundColor(Color.WHITE);
      }
      
      @Override
      public boolean onTouchEvent(MotionEvent event) {
         synchronized (_thread.getSurfaceHolder()) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
               path = new Path();
               path.moveTo(event.getX(), event.getY());
               path.lineTo(event.getX(), event.getY());
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
               path.lineTo(event.getX(), event.getY());
               _graphics.add(path);
               path = new Path();
               path.moveTo(event.getX(), event.getY());
               path.lineTo(event.getX(), event.getY());
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
               path.lineTo(event.getX(), event.getY());
               _graphics.add(path);
            }
            setBackgroundColor(Color.WHITE);      
            return true;
         }
      }

      @Override
      public void onDraw(Canvas canvas) {
         for (Path path : _graphics) {
            // canvas.drawPoint(graphic.x, graphic.y, mPaint);
            canvas.drawPath(path, mPaint);
         }
      }

      
      public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
      }

      
      public void surfaceCreated(SurfaceHolder holder) {
         _thread.setRunning(true);
         _thread.start();
      }

      
      public void surfaceDestroyed(SurfaceHolder holder) {
         boolean retry = true;
         _thread.setRunning(false);
         while (retry) {
            try {
               _thread.join();
               retry = false;
            } catch (InterruptedException e) {
               // we will try it again and again...
            }
         }
      }
   }

   class TutorialThread extends Thread {
      private SurfaceHolder _surfaceHolder;
      private Panel _panel;
      private boolean _run = false;

      public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
         _surfaceHolder = surfaceHolder;
         _panel = panel;
      }

      public void setRunning(boolean run) {
         _run = run;
      }

      public SurfaceHolder getSurfaceHolder() {
         return _surfaceHolder;
      }

      @Override
      public void run() {
         Canvas c;
         while (_run) {
            c = null;
            try {
               c = _surfaceHolder.lockCanvas(null);
               synchronized (_surfaceHolder) {
                  _panel.onDraw(c);
               }
            } finally {
               if (c != null) {
                  _surfaceHolder.unlockCanvasAndPost(c);
               }
            }
         }
      }
   }

   class GraphicObject {
      /**
       * Contains the coordinates of the graphic.
       */
      public class Coordinates {
         private int _x = 100;
         private int _y = 0;

         public int getX() {
            return _x + _bitmap.getWidth() / 2;
         }

         public void setX(int value) {
            _x = value - _bitmap.getWidth() / 2;
         }

         public int getY() {
            return _y + _bitmap.getHeight() / 2;
         }

         public void setY(int value) {
            _y = value - _bitmap.getHeight() / 2;
         }

         public String toString() {
            return "Coordinates: (" + _x + "/" + _y + ")";
         }
      }

      private Bitmap _bitmap;
      private Coordinates _coordinates;

      public GraphicObject(Bitmap bitmap) {
         _bitmap = bitmap;
         _coordinates = new Coordinates();
      }

      public Bitmap getGraphic() {
         return _bitmap;
      }

      public Coordinates getCoordinates() {
         return _coordinates;
      }
   }

}


As you can see I tried to get the image from the image view, but the application just force closes. Any Ideas? :(
User avatar
stece
Experienced Developer
Experienced Developer
 
Posts: 62
Joined: Wed Apr 21, 2010 10:50 am
Location: Belgium

Top

Return to Android 2D/3D Graphics - OpenGL Problems

Who is online

Users browsing this forum: Exabot [Bot] and 2 guests