Android签名捕获

Android签名捕获,android,Android,我正在开发android应用程序。在我的项目中,我有一项关于签名捕获的任务,即用户应在手机屏幕上保留他/她的签名,单击保存按钮后,签名必须存储在数据库中。我已经搜索并找到了一些链接,但仍然没有找到确切的答案。 我还尝试了TouchPaint.java,但在那里我没有找到布局的xml文件。 你能给我们提供一些示例代码吗?我将感谢您……您可能需要手势生成器 我觉得这个环节 会对你有用的。如果您需要再次检查签名 更新 你在说这个吗 那么这个示例不使用xml。它的视图是一个内部类(MyView)您可

我正在开发android应用程序。在我的项目中,我有一项关于签名捕获的任务,即用户应在手机屏幕上保留他/她的签名,单击保存按钮后,签名必须存储在数据库中。我已经搜索并找到了一些链接,但仍然没有找到确切的答案。 我还尝试了TouchPaint.java,但在那里我没有找到布局的xml文件。
你能给我们提供一些示例代码吗?我将感谢您……

您可能需要手势生成器

我觉得这个环节

会对你有用的。如果您需要再次检查签名

更新

你在说这个吗


那么这个示例不使用xml。它的视图是一个内部类(MyView)您可能需要手势生成器

我觉得这个环节

会对你有用的。如果您需要再次检查签名

更新

你在说这个吗


那么这个示例不使用xml。它的视图是一个内部类(MyView)

,任何人都可以在这里找到解决方案


它实际上会将签名写入文件,但更改并写入数据库非常简单。

对于任何正在寻找解决方案的人,您都可以在


实际上,它会将签名写入文件,但更改并写入数据库非常容易。

我知道这是一个老问题,但我需要实现自己的视图来捕获签名,因为我使用的是MonoForAndroid(C#不是Java)。所以我在这里添加了我的视图代码,以防有人需要它

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
    }

}

此外,我还有一个详细的示例,介绍了如何捕获签名。基本上你可以用两种不同的方式来做。或者将带有签名的视图捕获为图像,然后保存该位图(并可能将其发送到服务器)。或者,您可以捕获一个二维点阵列,然后以任何您想要的方式重建签名

我知道这是一个老问题,但我需要实现自己的视图来捕获签名,因为我使用的是MonoForAndroid(C#不是Java)。所以我在这里添加了我的视图代码,以防有人需要它

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
    }

}

此外,我还有一个详细的示例,介绍了如何捕获签名。基本上你可以用两种不同的方式来做。或者将带有签名的视图捕获为图像,然后保存该位图(并可能将其发送到服务器)。或者,您可以捕获一个二维点阵列,然后以任何您想要的方式重建签名

这是Has Altiar的C#Signature视图的Java版本, 我花了一段时间让它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();

这是Has Altiar的C#Signature视图的Java版本, 我花了一段时间让它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();


也许这个[相关问题][1]给了你一些提示。[1] :可能重复:可能这个[相关问题][1]给了你一些提示。[1] :可能重复:您好,谢谢您的回复。我只需要TouchPaint应用程序。但在执行应用程序时,我无法查看输出。我是否需要添加任何其他新文件来执行应用程序?我已经添加了另外两个类GraphicsActivity和PictureLayout…您可以在android sdk的API DemosHi中的com.example.android.API.graphics中找到TouchPaing/FingerPaint的完整工作示例,谢谢您的回复。我只需要TouchPaint应用程序。但在执行应用程序时,我无法查看输出。我是否需要添加任何其他新文件来执行应用程序?我已经添加了另外两个类GraphicsActivity和PictureLayout…您可以在android sdk的API演示中的com.example.android.API.graphics中找到TouchPaing/FingerPaint的完整工作示例您的“博客帖子”不存在。绘制后如何检索位图?我每次都会得到一张空白纸,当我画画的时候,它会粘在一起。但是在保存时,无法获得带有绘图的位图?+1谢谢您的代码,请参阅我的帖子是您的C#code的java版本更新了修复断开链接的答案您的“博客帖子”不存在。绘图后如何检索位图?我每次都会得到一张空白纸,当我画画的时候,它会粘在一起。但是在保存时,无法获得带有绘图的位图?+1谢谢您的代码,请参阅我的帖子是您的C#代码的java版本更新了修复损坏链接的答案是的。做了类似的事情,但我没有检查线路长度。我将其添加到运动事件向上和运动事件向下中。如果用户清除,则它将变为false。谢谢。这太棒了!工作完美!非常感谢。工作很有魅力!工作完美!!!非常感谢你,伙计@Jacks,您可以使用Canvas.drawBitmap(myBitmap,0,0)是的。做了类似的事情,但我没有检查线路长度。我将其添加到运动事件向上和运动事件向下中。如果用户清除,则它将变为false。谢谢。这太棒了!工作完美!非常感谢。工作很有魅力!工作完美!!!非常感谢你,伙计@Jacks,您可以使用Canvas.drawBitmap(myBitmap,0,0)