Skip to content

Instantly share code, notes, and snippets.

@jaboc83
Last active May 3, 2021 16:01
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save jaboc83/2559996 to your computer and use it in GitHub Desktop.
Save jaboc83/2559996 to your computer and use it in GitHub Desktop.
jQuery Signature Pad Compression/Decompression algorithm
/** Reinflates a compressed signature string:
resolution = a representation of the resolution in
pixels of the canvas which this signature will be drawn
e.g. {x:800,y:200}
*/
var inflateToJsonSignature = function (deflatedSig, resolution) {
var components = [],
modifier = 1,
compressWithResolution = /^(?:\[(\d+)x(\d+)\])?([\w\W]*)/,
parsedSigString = deflatedSig.match(compressWithResolution),
widthModifier, heightModifier, i,
sigString, deflatedLen,
componentsLength;
// If the previously compressed signature had a resolution,
// attempt to scale to fit the new canvas
if (parsedSigString && resolution) {
widthModifier = resolution.x / (parsedSigString[1] || 1);
heightModifier = resolution.y / (parsedSigString[2] || 1);
modifier = widthModifier < heightModifier ? widthModifier : heightModifier;
deflatedSig = parsedSigString[3];
}
// Get each byte of the deflated signature as a unicode char
// and convert to a decimal coordinate value.
// e.g. '}' => 125
// Stuff the result in our output array
deflatedLen = deflatedSig.length;
for (i = 0; i < deflatedSig.length; i++) {
components.push((deflatedSig[i].charCodeAt()).toString());
}
// Rebuild the signature string from the result array above.
// Every 4 chars represent the two sets of x,y coordinates
componentsLength = components.length;
sigString = "[";
for (i = 0; i < componentsLength; i = i + 4) {
sigString += (
'{"lx":' + Math.round(components[i] * modifier) +
',"ly":' + Math.round(components[i + 1] * modifier) +
',"mx":' + Math.round(components[i + 2] * modifier) +
',"my":' + Math.round(components[i + 3] * modifier) + '},');
}
return sigString.substring(0, (sigString.length - 1)) + "]";
};
/** Deflates(compresses) a json signature string:
resolution = a representation of the resolution in
pixels of the canvas which this signature came from
e.g. {x:800,y:200}
*/
var deflateFromJsonSignature = function (jsonSig, resolution) {
var replacedSig,
compressString = "",
components,
componentsLength, i;
// Grab only the digits from the string
components = jsonSig.match(/\d+/g);
componentsLength = components.length
for (i = 0; i < componentsLength; i = i + 1) {
// don't save lines drawn outside the canvas. just draw to the edge.
components[i] = components[i] < 0 ? 0 : components[i];
// convert coordinate to a unicode value
// e.g. 125 => '}'
// Append the result to the compressed string
compressString += String.fromCharCode(parseInt(components[i].toString()));
}
// if a resolution was specified add it to the front of the compression string to allow
// better scaling if the canvas changes size in the future
if (resolution) {
compressString = "[" + resolution.x + "x" + resolution.y + "]" + compressString;
}
return compressString;
}
@jakemoeningspok
Copy link

@j-max-creator That entirely depends on the back-end you are using. The form submission code from @matt-hwy1 's example will make a POST back to your server and depending on the language / framework you'll have to parse the compressed form data from the request and handle the saving of the compressed sig string into whatever your database of choice is. I think that this might be a good resource to start with: https://developer.mozilla.org/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data

@j-max-creator
Copy link

Hi. Sorry yeah I'm slightly beyond that and understand saving/retrieving from sql server. Sig works fine without compression but when often runs over 8000 limit for varchar. I have it compressing and saving to the database but when I try to re-inflate i'm gettting closed angle bracket sometimes within the compressed json which is then causing the redraw to fail... I am working on it and will probably get it. Thought it might have been charset or data type issue but still getting > within the compressed json. Any help/ideas would be welcome...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment