Capturing a signature in 1C using a graphics tablet

Signing documents is an integral part of many business processes. Whether it is concluding an employment contract, issuing material assets or issuing invoices: often in such cases it is necessary to print out the document and sign it. To simplify and automate this process, we have developed a solution that allows you to receive signed documents directly in 1C, eliminating the need for printing, signing and subsequent scanning.

In this example we are using a One by Wacom S-size graphics tablet. This is a compact device that easily connects to computers running Windows (version 7 and above) and Mac OS (version 10.10 and above).

How our solution works

The user, being at his workplace, prints the document. At the moment of generating a spreadsheet document, the user is given the opportunity to “draw” his signature on a graphics tablet. The image from the tablet is displayed in a separate form window.

Next, we convert the image with the signature into binary data and insert it into the desired location on the printed form of the document. The result is a finished document that can be saved in the 1C database or printed.

Signature Capture Algorithm

Let's consider the signature capture algorithm using the example of creating external processing. In the processing form, add an attribute of the “String” type (unlimited length) and call it “HTML Field”. This detail will be displayed on the form.

So that the user can “draw” a signature directly on the form, we assign a certain value to this attribute. Let's do this through the “When CreatedOnServer” event. For convenience, we use the Text Document type processing layout, which contains JavaScript code.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body style="margin:0;padding:0">
<canvas id="canvas" width="800" height="600"
    style="background-color:#eee; border: 0px solid #ccc; margin:0px;"></canvas>
<canvas id="canvas2" hidden width="330" height="90"
    style="background-color:#fff; border: 0px solid #aaa; margin:0px;"></canvas>
<script>
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d"); 
  
const canvas2 = document.getElementById("canvas2");
const context2 = canvas2.getContext("2d");

const mouse = { x:0, y:0};      // координаты мыши
let draw = false;     
  
function resizeCanvas() {
	canvas.width = window.innerWidth-5;
	canvas.height = window.innerHeight-5;
}

resizeCanvas();

function clearImage() {
	context.clearRect(0, 0, canvas.width, canvas.height);
	context2.clearRect(0, 0, canvas2.width, canvas2.height);
}

function saveImage(saveTo) {
   
	const w = canvas.width;
	const h = canvas.height;
 
    let minX = w;
	let minY = h;
	let maxX = 0;
	let maxY = 0;

	let imgData = context.getImageData(0,0,w,h);
	for (let i = 0; i < imgData.data.length; i += 4) {
		if (imgData.data[i+3] > 0){
			let current_top = Math.floor(i/4/w);
  			let current_left = Math.floor((i/4/w - current_top)*w);
           
			if (minX > current_left)
				minX = current_left;	
           
			if (maxX < current_left)
				maxX = current_left; 

			if (minY > current_top)
				minY = current_top; 				

			if (maxY < current_top)
				maxY = current_top;
		}
	}       
   
	let cropWidth = maxX-minX;
	let cropHeight = maxY-minY;
   	let aspect = cropWidth/cropHeight;
	let destX = (330-90*aspect)/2; 
	context2.drawImage(canvas, minX, minY, maxX-minX, maxY-minY, destX, 0, 90*aspect, 90);
	var image = canvas2.toDataURL("image/png").replace("image/png", "image/octet-stream"); 
	return image;
} 

window.addEventListener('resize', (e) => {
	resizeCanvas();
});

// нажатие мыши
canvas.addEventListener("mousedown", function(e){
      
    mouse.x = e.pageX - this.offsetLeft;
    mouse.y = e.pageY - this.offsetTop;
    draw = true;
    context.beginPath();
    context.moveTo(mouse.x, mouse.y);
});
// перемещение мыши
canvas.addEventListener("mousemove", function(e){
      
    if(draw==true){
      
        mouse.x = e.pageX - this.offsetLeft;
        mouse.y = e.pageY - this.offsetTop;
        context.lineTo(mouse.x, mouse.y);
        context.stroke();
    }
});
 
// отпускаем мышь
canvas.addEventListener("mouseup", function(e){
      
    mouse.x = e.pageX - this.offsetLeft;
    mouse.y = e.pageY - this.offsetTop;
    context.lineTo(mouse.x, mouse.y);
    context.stroke();
    context.closePath();
    draw = false;
	
});
</script>
</body>
</html>

We create a processing layout, add the necessary JavaScript code, and then in the “When CreatedOnServer” event we assign a value to the “HTML Field” attribute.

What happened

We created a kind of graphic editor right in 1C. Now, by moving the mouse cursor in the “HTML Field”, you can draw on the platform, which is very convenient.

Now we need to “capture” the drawn signature and convert it into an image represented as binary data. This will allow you to use the signature in the future as a regular image with a transparent background for inserting into spreadsheet documents or printing.

To do this, create a command on the form and set an action for it with the “&OnClient” compilation directive.

Results

The solution was successfully applied in real practice when working with a customer. It helped reduce the number of steps required: from printing a document and manually signing it on paper, to subsequent scanning. Now the entire process of signing documents is faster and more convenient, right in 1C.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *