在Android图像上创建签名?

时间:2012-11-12 07:01:07

标签: android

我正在创建一个在文件图像上创建签名的应用程序。在这里,我将图像文件从存储卡加载到应用程序,并使用Canvas Paint可以通过绘图手动创建签名。

此处的问题是客户登录特定位置的应用程序要求。我的代码允许客户可以在客户想要的任何地方登录,例如在窗户上绘画。现在,我只想在特定区域签名......帮助我......

这是我的代码

Main.java

public class Longvan extends Activity implements OnClickListener, OnTouchListener {
  ImageView choosenImageView;
  Button choosePicture;
  Button savePicture;
  Bitmap bmp;
  Bitmap alteredBitmap;
  Canvas canvas;
  Paint paint;
  Matrix matrix;
  float downx = 0;
  float downy = 0;
  float upx = 0;
  float upy = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_longvan);
    int currentOrientation = getResources().getConfiguration().orientation;
    if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
       setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
    }
    else {
       setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
    }

    choosenImageView = (ImageView) this.findViewById(R.id.ChoosenImageView);
    choosePicture = (Button) this.findViewById(R.id.ChoosePictureButton);
    savePicture = (Button) this.findViewById(R.id.SavePictureButton);
    savePicture.setOnClickListener(this);
    choosePicture.setOnClickListener(this);
    choosenImageView.setOnTouchListener(this);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_longvan, menu);
    return true;
}

@Override
public boolean onTouch(View v, MotionEvent event) {
    // TODO Auto-generated method stub
     int action = event.getAction();
        switch (action) {
        case MotionEvent.ACTION_DOWN:
          downx = event.getX();
          downy = event.getY();
          break;
        case MotionEvent.ACTION_MOVE:
          upx = event.getX();
          upy = event.getY();
          canvas.drawLine(downx, downy, upx, upy, paint);
          choosenImageView.invalidate();
          downx = upx;
          downy = upy;
          break;
        case MotionEvent.ACTION_UP:
          upx = event.getX();
          upy = event.getY();
          canvas.drawLine(downx, downy, upx, upy, paint);
          choosenImageView.invalidate();
          break;
        case MotionEvent.ACTION_CANCEL:
          break;
        default:
          break;
        }
        return true;      
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    if (v == choosePicture) {
          Intent choosePictureIntent = new Intent(
              Intent.ACTION_PICK,
              android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
          startActivityForResult(choosePictureIntent, 0);
        } else if (v == savePicture) {
          if (alteredBitmap != null) {
            ContentValues contentValues = new ContentValues(3);
            contentValues.put(Media.DISPLAY_NAME, "Draw On Me");
            Uri imageFileUri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, contentValues);
            try {
              OutputStream imageFileOS = getContentResolver().openOutputStream(imageFileUri);
              alteredBitmap.compress(CompressFormat.JPEG, 90, imageFileOS);
              Toast t = Toast.makeText(this, "Thank you! Image Saved!", Toast.LENGTH_LONG);
              t.show();
            } catch (Exception e) {
              Log.v("EXCEPTION", e.getMessage());
            }
          }
        }
}

 protected void onActivityResult(int requestCode, int resultCode,
          Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        if (resultCode == RESULT_OK) {
          Uri imageFileUri = intent.getData();
          try {
            BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
            bmpFactoryOptions.inJustDecodeBounds = true;
            bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                    imageFileUri), null, bmpFactoryOptions);
            bmpFactoryOptions.inJustDecodeBounds = false;
            bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                    imageFileUri), null, bmpFactoryOptions);
            alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),bmp.getConfig());
            canvas = new Canvas(alteredBitmap);
            paint = new Paint();
            paint.setColor(Color.BLUE);
            paint.setStrokeWidth(2);
            matrix = new Matrix();
            canvas.drawBitmap(bmp, matrix, paint);
            choosenImageView.setImageBitmap(alteredBitmap);
            choosenImageView.setOnTouchListener(this);
          } catch (Exception e) {
            Log.v("ERROR", e.toString());
          }
        }
      }
            }

1 个答案:

答案 0 :(得分:6)

用于输入签名的特定视图怎么样?这样的事情:https://github.com/CoatedMoose/CustomViews/tree/master/library/src/com/coatedmoose/customviews

然后,为Bitmap添加此setter:

public void setImage(Bitmap bitmap) {
    this.mBitmap = bitmap;
    this.invalidate();
}

或者,如果您不希望将应用的位图作为签名视图的一部分(将其用作背景,而不是画布),请将onDraw方法替换为:

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.TRANSPARENT);
    canvas.drawBitmap(mBitmap, 0, 0, mPaint);
    canvas.drawPath(mPath, mPaint);
}

然后只使用mSignatureView.setBackgroundResource(R.drawable.background);

编辑:

只需使用coatedMoose中的代码创建一个Class,并在布局XML中使用它:

<com.example.myapp.gui.views.SignatureView
  android:id="@+id/signature"
  android:layout_width="match_parent"
  android:layout_height="80dp"/>

在代码中的某个位置,甚至作为XML属性,您可以设置背景。

编辑:signatureView类:

    package me.other;

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 {
    @SuppressWarnings("unused")
    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.TRANSPARENT);
            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.TRANSPARENT);
        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:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.example.mysignatureviewapp.views.SignatureView 
        android:id="@+id/sign"
        android:layout_width="match_parent"
        android:layout_height="204dp">
    </com.example.mysignatureviewapp.views.SignatureView>
</RelativeLayout>

onCreate()方法中:

private SignatureView sign;
//
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mysignatureviewlayout);
    sign = (SignatureView) findViewById(R.id.sign);
    sign.setBackgroundResource(R.drawable.mybackgrounddrawable);
}

//get your signature when you press, say, the back button
@Override
public void onBackPressed() {
    Bitmap mySignature = sign.getImage();
    //do something with bitmap
}

同时获得背景和签名:

BitmapDrawable mySignature = new BitmapDrawable(sign.getImage());
Drawable background = sign.getBackground();
LayerDrawable ld = new LayerDrawable(new Drawable[] { mySignature, background});