2011-03-28 112 views
8

我想在android中创建数字签名应用程序。它应该捕获用户签名并将其作为图像存储。如果有人知道,请让我知道。Android中的数字签名

+0

我加了一些代码,现在它会覆盖你的整个问题。工作时检查答案。 – stealthjong 2012-11-14 10:34:33

回答

0

这可以在Gestureoverlay的帮助下完成。这在APIDemos中有所体现。下面的链接必须是有帮助的:

digital Signature

10

尝试使用自定义视图的手势:

package com.example.myapp.gui.views; 

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.Path; 
import android.os.SystemClock; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.view.View; 

/** 
* A simple view to capture a path traced onto the screen. Initially intended to be used to captures signatures. 
* 
* @author Andrew Crichton 
* @version 0.1 
*/ 
public class SignatureView extends View { 
    private Path mPath; 
    private Paint mPaint; 
    private Paint bgPaint = new Paint(Color.TRANSPARENT); 

    private Bitmap mBitmap; 
    private Canvas mCanvas; 

    private float curX, curY; 

    private static final int TOUCH_TOLERANCE = 4; 
    private static final int STROKE_WIDTH = 4; 

    public SignatureView(Context context) { 
     super(context); 
     init(); 
    } 
    public SignatureView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 
    public SignatureView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(); 
    } 
    private void init() { 
     setFocusable(true); 
     mPath = new Path(); 
     mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 
     mPaint.setColor(Color.WHITE); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeWidth(STROKE_WIDTH); 
    } 
    public void setSigColor(int color) { 
     mPaint.setColor(color); 
    } 
    public void setSigColor(int a, int red, int green, int blue) { 
     mPaint.setARGB(a, red, green, blue); 
    } 
    public boolean clearSignature() { 
     if (mBitmap != null) 
      createFakeMotionEvents(); 
     if (mCanvas != null) { 
      mCanvas.drawColor(Color.BLACK); 
      mCanvas.drawPaint(bgPaint); 
      mPath.reset(); 
      invalidate(); 
     } 
     else { 
      return false; 
     } 
     return true; 
    } 
    public Bitmap getImage() { 
     return this.mBitmap; 
    } 
    public void setImage(Bitmap bitmap) { 
     this.mBitmap = bitmap; 
     this.invalidate(); 
    } 
    @Override 
    protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { 
     int bitmapWidth = mBitmap != null ? mBitmap.getWidth() : 0; 
     int bitmapHeight = mBitmap != null ? mBitmap.getWidth() : 0; 
     if (bitmapWidth >= width && bitmapHeight >= height) 
      return; 
     if (bitmapWidth < width) 
      bitmapWidth = width; 
     if (bitmapHeight < height) 
      bitmapHeight = height; 
     Bitmap newBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 
     Canvas newCanvas = new Canvas(); 
     newCanvas.setBitmap(newBitmap); 
     if (mBitmap != null) 
      newCanvas.drawBitmap(mBitmap, 0, 0, null); 
     mBitmap = newBitmap; 
     mCanvas = newCanvas; 
    } 
    private void createFakeMotionEvents() { 
     MotionEvent downEvent = MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis()+100, MotionEvent.ACTION_DOWN, 1f, 1f ,0); 
     MotionEvent upEvent = MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis()+100, MotionEvent.ACTION_UP, 1f, 1f ,0); 
     onTouchEvent(downEvent); 
     onTouchEvent(upEvent); 
    } 
    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawColor(Color.BLACK); 
     canvas.drawBitmap(mBitmap, 0, 0, mPaint); 
     canvas.drawPath(mPath, mPaint); 
    } 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     float x = event.getX(); 
     float y = event.getY(); 

     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      touchDown(x, y); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      touchMove(x, y); 
      break; 
     case MotionEvent.ACTION_UP: 
      touchUp(); 
      break; 
     } 
     invalidate(); 
     return true; 
    } 
    /**---------------------------------------------------------- 
    * Private methods 
    **---------------------------------------------------------*/ 

    private void touchDown(float x, float y) { 
     mPath.reset(); 
     mPath.moveTo(x, y); 
     curX = x; 
     curY = y; 
    } 

    private void touchMove(float x, float y) { 
     float dx = Math.abs(x - curX); 
     float dy = Math.abs(y - curY); 
     if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { 
      mPath.quadTo(curX, curY, (x + curX)/2, (y + curY)/2); 
      curX = x; 
      curY = y; 
     } 
    } 

    private void touchUp() { 
     mPath.lineTo(curX, curY); 
     if (mCanvas == null) { 
      mCanvas = new Canvas(); 
      mCanvas.setBitmap(mBitmap); 
     } 
     mCanvas.drawPath(mPath, mPaint); 
     mPath.reset(); 
    } 
} 

然后,在你的XML使用这个类:<com.example.myapp.gui.views.SignatureView .../> 要获得绘制的签名,用这个:Bitmap bmp = ((SignatureView)findViewById(R.id.signatureview)).getImage();

最后,您可以保存该位图,此代码:

public void saveBitmap(Bitmap bmp) { 
    try { 
     String root = Environment.getExternalStorageDirectory().getAbsolutePath() + "/"; 
     String filepath = root + "signature.jpg"; 

     FileOutputStream fos = new FileOutputStream(filepath); 
     bmp.compress(CompressFormat.JPEG, 100, fos); 
     fos.flush(); 
     fos.close(); 
    } 
    catch(Exception e) { 
     Log.e("Could not save", e.getMessage()); 
     e.printStackTrace(); 
    } 
} 

这会将签名保存在SD卡的根目录中作为signature.jpeg。对于写作部分,确保有这个权限在你的清单:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

+0

..非常感谢你!但是当我画线或任何形状为什么它改变它的位置?请你能帮忙吗? – Rauf 2013-10-24 10:40:32

+0

@Rauf你是说当你绘制时,Android会在你绘制的地方旁画几个(几十个)像素? – stealthjong 2013-10-24 11:48:43

+0

no ..我画点从A点(200,200)到B(200,400),然后当我释放指针/触摸线被移动到左上角像X(50,50)到Z(50,250)..我尽我所能解释这个:) – Rauf 2013-10-25 07:12:53

4

希望这个代码可以帮助你:)

esign_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 


    <android.gesture.GestureOverlayView 
     android:id="@+id/signaturePad" 
     android:layout_width="match_parent" 
     android:layout_height="0dp" 
     android:layout_weight="5" 
     android:background="@android:color/white" 
     android:clickable="false" 
     android:eventsInterceptionEnabled="true" 
     android:fadeEnabled="false" 
     android:gestureColor="#0000ff" 
     android:gestureStrokeLengthThreshold="0.1" 
     android:gestureStrokeType="multiple" 
     android:longClickable="false" 
     android:orientation="vertical" 
     android:uncertainGestureColor="#000000" 
     android:splitMotionEvents="true" 
     android:fadeOffset="10000000"> 

    </android.gesture.GestureOverlayView> 

    <RelativeLayout 
     android:id="@+id/rellay_esign_donebutton" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:paddingBottom="10dp" 
     > 
<LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="horizontal" 
     android:gravity="center" 
     > 
     <Button 
      android:id="@+id/DoneButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Done" /> 

     <Button 
      android:id="@+id/ClearButton" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Clear" /> 
</LinearLayout> 
    </RelativeLayout> 

</LinearLayout> 

Esignature.java

public class Esignature extends Activity { 
    GestureOverlayView gestureView; 
    String path; 
    File file; 
    Bitmap bitmap; 
    public boolean gestureTouch=false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.esign_main); 



     Button donebutton = (Button) findViewById(R.id.DoneButton); 
     donebutton.setText("Done"); 
     Button clearButton = (Button) findViewById(R.id.ClearButton); 
     clearButton.setText("Clear"); 

     path=Environment.getExternalStorageDirectory()+"/signature.png"; 
     file = new File(path); 
     file.delete(); 
     gestureView = (GestureOverlayView) findViewById(R.id.signaturePad); 
     gestureView.setDrawingCacheEnabled(true); 

     gestureView.setAlwaysDrawnWithCacheEnabled(true); 
     gestureView.setHapticFeedbackEnabled(false); 
     gestureView.cancelLongPress(); 
     gestureView.cancelClearAnimation(); 
     gestureView.addOnGestureListener(new OnGestureListener() { 

      @Override 
      public void onGesture(GestureOverlayView arg0, MotionEvent arg1) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onGestureCancelled(GestureOverlayView arg0, 
        MotionEvent arg1) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onGestureEnded(GestureOverlayView arg0, MotionEvent arg1) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void onGestureStarted(GestureOverlayView arg0, 
        MotionEvent arg1) { 
       // TODO Auto-generated method stub 
       if (arg1.getAction()==MotionEvent.ACTION_MOVE){ 
        gestureTouch=false;      
      } 
      else 
      { 
        gestureTouch=true; 
      } 
      }}); 

     donebutton.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // TODO Auto-generated method stub 
       try { 
        bitmap = Bitmap.createBitmap(gestureView.getDrawingCache()); 
        file.createNewFile(); 
        FileOutputStream fos = new FileOutputStream(file); 
        fos = new FileOutputStream(file); 
        // compress to specified format (PNG), quality - which is 
        // ignored for PNG, and out stream 
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); 
        fos.close(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      if(gestureTouch==false) 
      { 
       setResult(0); 
       finish(); 
      } 
      else 
      { 
       setResult(1); 
       finish(); 
      } 
      } 
     }); 

     clearButton.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       // TODO Auto-generated method stub 
       gestureView.invalidate(); 
       gestureView.clear(true); 
       gestureView.clearAnimation(); 
       gestureView.cancelClearAnimation(); 
      } 
     }); 
    } 





} 
0

对于白色背景的JPG文件:

gestureView.setDrawingCacheBackgroundColor(Color.WHITE); 

并使用Harshal Benake溶液

bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);