Подтвердить что ты не робот

Android Signature Capture

Я работаю над приложением для Android. В моем проекте у меня есть задача в отношении захвата подписи, то есть пользователь должен сохранить свою подпись на экране мобильного и один раз сохранить щелкнув, что подпись должна храниться в базе данных. Я искал и нашел некоторые ссылки, но все же я не нашел точного решения.    Я также пробовал TouchPaint.java, но там я не нашел xml файл для макета.    Не могли бы вы предложить нам пример кода? Я буду благодарен вам....

4b9b3361

Ответ 2

Вот рабочая версия Java, имеющая представление подписи AlTaiar С#, Потребовалось некоторое время, чтобы заставить его работать на 100% правильно

public class CaptureSignatureView extends View {

    private Bitmap _Bitmap;
    private Canvas _Canvas;
    private Path _Path;
    private Paint _BitmapPaint;
    private Paint _paint;
    private float _mX;
    private float _mY;
    private float TouchTolerance = 4;
    private float LineThickness = 4;

    public CaptureSignatureView(Context context, AttributeSet attr) {
        super(context, attr);
        _Path = new Path();
        _BitmapPaint = new Paint(Paint.DITHER_FLAG);
        _paint = new Paint();
        _paint.setAntiAlias(true);
        _paint.setDither(true);
        _paint.setColor(Color.argb(255, 0, 0, 0));
        _paint.setStyle(Paint.Style.STROKE);
        _paint.setStrokeJoin(Paint.Join.ROUND);
        _paint.setStrokeCap(Paint.Cap.ROUND);
        _paint.setStrokeWidth(LineThickness);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        _Bitmap = Bitmap.createBitmap(w, (h > 0 ? h : ((View) this.getParent()).getHeight()), Bitmap.Config.ARGB_8888);
        _Canvas = new Canvas(_Bitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE);
        canvas.drawBitmap(_Bitmap, 0, 0, _BitmapPaint);
        canvas.drawPath(_Path, _paint);
    }

    private void TouchStart(float x, float y) {
        _Path.reset();
        _Path.moveTo(x, y);
        _mX = x;
        _mY = y;
    }

    private void TouchMove(float x, float y) {
        float dx = Math.abs(x - _mX);
        float dy = Math.abs(y - _mY);

        if (dx >= TouchTolerance || dy >= TouchTolerance) {
            _Path.quadTo(_mX, _mY, (x + _mX) / 2, (y + _mY) / 2);
            _mX = x;
            _mY = y;
        }
    }

    private void TouchUp() {
        if (!_Path.isEmpty()) {
            _Path.lineTo(_mX, _mY);
            _Canvas.drawPath(_Path, _paint);
        } else {
            _Canvas.drawPoint(_mX, _mY, _paint);
        }

        _Path.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        super.onTouchEvent(e);
        float x = e.getX();
        float y = e.getY();

        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN:
                TouchStart(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                TouchMove(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                TouchUp();
                invalidate();
                break;
        }

        return true;
    }

    public void ClearCanvas() {
        _Canvas.drawColor(Color.WHITE);
        invalidate();
    }

    public byte[] getBytes() {
        Bitmap b = getBitmap();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        b.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    public Bitmap getBitmap() {
        View v = (View) this.getParent();
        Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
        v.draw(c);

        return b;
    }
}

Я попробовал предложение Роба Кролла, которое сработало хорошо, но оно прямолинейно, делая подпись не похожей на человека. Если вы знаете, что я имею в виду: P

Вот как вы добавляете представление на пустой линейный макет

LinearLayout mContent = (LinearLayout) findViewById(R.id.linearLayout);
CaptureSignatureView mSig = new CaptureSignatureView(this, null);
mContent.addView(mSig, LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);

Вот как получить байты или растровые изображения подписи

byte[] signature = mSig.getBytes();
Bitmap signature = mSig.getBitmap();

Ответ 3

вам, вероятно, нужен создатель жестов.

Я думаю, что эта ссылка.

http://android-developers.blogspot.com/2009/10/gestures-on-android-16.html

будет вам полезен. если вам нужно снова проверить подпись.

UPDATE

Вы говорите об этом

http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.html

то этот пример не использует xml. он имеет представление как внутренний класс (MyView)

Ответ 4

Я знаю, что это старый вопрос, но мне нужно было реализовать собственное представление для захвата подписи, потому что я использую MonoForAndroid (С#, а не Java). Поэтому я добавляю свой код View здесь, если кому-то это понадобится.

using System;
using Android.Content;
using Android.Graphics;
using Android.Views;

namespace MyApp.Views
{
    public class CaptureSignatureView : View
    {
        public CaptureSignatureView(Context c, SignatureData signatureData) : base(c)
        {
            SignatureData = signatureData;
            _Path = new Path();
            _BitmapPaint = new Paint(PaintFlags.Dither);
            _paint = new Paint
            {
                AntiAlias = true,
                Dither = true,
                Color = Color.Argb(255, 0, 0, 0)
            };
            _paint.SetStyle(Paint.Style.Stroke);
            _paint.StrokeJoin = Paint.Join.Round;
            _paint.StrokeCap = Paint.Cap.Round;
            _paint.StrokeWidth = 8;
        }

        protected override void OnSizeChanged(int w, int h, int oldw, int oldh)
        {
            base.OnSizeChanged(w, h, oldw, oldh);
            _Bitmap = Bitmap.CreateBitmap(w, (h > 0 ? h : ((View)this.Parent).Height), Bitmap.Config.Argb8888);
            _Canvas = new Canvas(_Bitmap);
        }

        protected override void OnDraw(Canvas canvas)
        {
            canvas.DrawColor(Color.White);
            canvas.DrawBitmap(_Bitmap, 0, 0, _BitmapPaint);
            canvas.DrawPath(_Path, _paint);
        }

        private float _mX, _mY;
        private const float TouchTolerance = 4;

        private void TouchStart(float x, float y)
        {
            _Path.Reset();
            _Path.MoveTo(x, y);
            _mX = x;
            _mY = y;
            SignatureData.AddPoint(SignatureState.Start, (int)x, (int)y);
        }

        private void TouchMove(float x, float y)
        {
            float dx = Math.Abs(x - _mX);
            float dy = Math.Abs(y - _mY);

            if (dx >= TouchTolerance || dy >= TouchTolerance)
            {
                _Path.QuadTo(_mX, _mY, (x + _mX) / 2, (y + _mY) / 2);
                SignatureData.AddPoint(SignatureState.Move, (int)x, (int)y);
                _mX = x;
                _mY = y;
            }
        }

        private void TouchUp()
        {
            if (!_Path.IsEmpty)
            {
                _Path.LineTo(_mX, _mY);
                _Canvas.DrawPath(_Path, _paint);
            }
            else
            {
                _Canvas.DrawPoint(_mX, _mY, _paint);
            }
            SignatureData.AddPoint(SignatureState.End, (int)_mX, (int)_mY);

            _Path.Reset();
        }

        public override bool OnTouchEvent(MotionEvent e)
        {
            var x = e.GetX();
            var y = e.GetY();

            switch (e.Action)
            {
                case MotionEventActions.Down:
                    TouchStart(x, y);
                    Invalidate();
                    break;
                case MotionEventActions.Move:
                    TouchMove(x, y);
                    Invalidate();
                    break;
                case MotionEventActions.Up:
                    TouchUp();
                    Invalidate();
                    break;
            }
            return true;
        }

        public void ClearCanvas()
        {
            _Canvas.DrawColor(Color.White);
            Invalidate();
        }

        public Bitmap CanvasBitmap()
        {
            return _Bitmap;
        }

        public void Clear()
        {
            ClearCanvas();
            SignatureData = new SignatureData();
        }

        #region Implementation

        private Bitmap _Bitmap;
        private Canvas _Canvas;
        private readonly Path _Path;
        private readonly Paint _BitmapPaint;
        private readonly Paint _paint;
        public  SignatureData SignatureData;

        #endregion
    }

}

Кроме того, у меня есть запись в блоге, в которой подробно описывается, как захватить подпись. В принципе, вы можете сделать это двумя разными способами. Либо вы захватываете представление с подписью в качестве изображения, и вы сохраняете это растровое изображение (и, возможно, отправляете его на сервер). Или вы могли бы просто захватить двумерный массив точек и восстановить подпись так, как хотите.