MarvinKlein1508 / SignaturePad

A simple to use blazor component to draw custom signatures.
MIT License
78 stars 12 forks source link

Minimum signature size #22

Open clodewyks opened 11 months ago

clodewyks commented 11 months ago

We are facing an interesting issue where touch on the canvas will cause the byte[] of the signature to not be an empty array.

We setup the SignaturePad as follows

<SignaturePad.SignaturePad @bind-Value="Signature" Options="_options" ShowClearButton="true" />

private SignaturePad.SignaturePadOptions _options = new SignaturePad.SignaturePadOptions
    {
        LineCap = SignaturePad.LineCap.Round,
        LineJoin = SignaturePad.LineJoin.Round,
        LineWidth = 1,
        BackgroundColor = "rgb(255,255,255)"
    };

@code
{
    public byte[] Signature { get; set; } = Array.Empty<byte>();
}

With a button linked to the value of the Signature byte[]:

<MudButton Variant="Variant.Outlined" OnClick="SaveSignature" FullWidth="true" Color="Color.Primary" **Disabled="(Signature == Array.Empty<byte>())"**>Submit</MudButton>

When touching on the signature pad, but not drawing a signature, the button still becomes enabled.

Is there a way to set a "minimum acceptable signature" on the control? We will be happy to contribute of you have an idea of how we can achieve this.

MarvinKlein1508 commented 11 months ago

When touching on the signature pad, but not drawing a signature, the button still becomes enabled.

This is normal. Every touch generates a small dot on the signature. Just like you tipping with a pen of a paper.

Is there a way to set a "minimum acceptable signature"

I do not handle any validation within this component. I believe this should be done outside of it. Basically what you can do is check the length of your signature. It grows with every update to the signature itself.

For example: Disabled="Signature.Length < 500"

clodewyks commented 11 months ago

Thank you @MarvinKlein1508 , a simple solution.

The only issue is the length of the byte[] based on device type, a "touch" on desktop yields a much higher Length than mobile.

Any suggestions?

MarvinKlein1508 commented 11 months ago

@clodewyks this makes sense. The canvas is much larger on desktop than on mobile. So it depends on your screen size.

you could overrite the signature class and define fixed width for desktop or you'll need to calculate your desired based size for your device width.

JosipNizetic commented 3 months ago

Good morning,

Sorry for bothering. Maybe to use (Signature bounding box area) / (full area )as a check. For example all below 10% are not ok..

  private double? RegionCalculate(byte[] fileBytes)
  {
      string decodedText = Encoding.UTF8.GetString(fileBytes);

      string base64Png = decodedText.Split(',')[1];

      byte[] pngBytes = Convert.FromBase64String(base64Png);

      using (var ms = new System.IO.MemoryStream(pngBytes))
      {
          using (Bitmap image = new Bitmap(ms))
          {
              int minX = image.Width;
              int minY = image.Height;
              int maxX = 0;
              int maxY = 0;
              bool foundNonEmptyPixel = false;

              for (int y = 0; y < image.Height; y++)
              {
                  for (int x = 0; x < image.Width; x++)
                  {
                      Color pixelColor = image.GetPixel(x, y);

                      if (pixelColor.R != 0 || pixelColor.G != 0 || pixelColor.B != 0)
                      {
                          foundNonEmptyPixel = true;
                          if (x < minX) minX = x;
                          if (x > maxX) maxX = x;
                          if (y < minY) minY = y;
                          if (y > maxY) maxY = y;
                      }
                  }
              }

              if (foundNonEmptyPixel)
              {
                  double boundingBoxArea = (maxX - minX + 1) * (maxY - minY + 1);
                  double percentageArea = boundingBoxArea / (image.Width * image.Height) * 100;

                  return percentageArea;
              }
          }
      }
      return null;
  }

Best regards, Josip