ana*_*xon 7 base64 canvas electronic-signature topaz-signatures
我正在开发一个移动应用程序(离子),其中有一个用户签名字段.用户需要用手指在画布上签名.
现在这个应用程序有web版本,他们使用topaz sigweb来做到这一点.现在要保存签名并在两端查看我需要某种转换.
我检查了sigweb的文档,他们以ASCHII十六进制格式保存签名.我不确定他们是否使用任何类型的内部加密,因为我无法将十六进制字符串转换为任何有效的基数64.
我不确定是否还有其他方法可以做到这一点.如果有人有任何想法请分享.
提前致谢.
小智 3
我意识到这有点旧了,但我确信还有很多其他人也有同样的问题。
当我需要在标准桌面或移动浏览器中向最终用户显示签名而无需插件或安装时,我遇到了完全相同的问题。与 Topaz 交谈,有一个选项可以使用 PHP 组件对象模型在服务器端运行 ActiveX 来创建图像。不幸的是,这仅适用于 Windows 服务器,并且需要大量的修改。我只设法让它在我的测试台上工作,但对于我的 Linux 生产服务器来说毫无用处。我再次联系 Topaz,他们说唯一的其他选择是 Java 小程序!?
活动X!Java 小程序!现在是 2019 年,不是 2009 年!(抱歉,我在感叹号上过量了,但是天啊)。
最后我决定尝试自己解码它并最终想出了这个 PHP 函数来创建 SVG。他们使用的格式是专有的(实际上有点乱),但本质上它只是十六进制、坐标和笔画长度——所以对于某人来说,将下面的格式转换到任何其他平台应该很容易。
//Requires $SigString and accepts optional filename.
//If filename is supplied the image will be written to that file
//If no filename is supplied the SVG image will be returned as a string which can be echoed out directly
function sigstring2svg($SigString, $filename = NULL)
{
$raw = hex2bin($SigString); //Convert Hex
$arr = explode(PHP_EOL, $raw); //Split into array
if ($arr[1] > 0) { //Check if signature is empty
$coords = array_slice($arr, 2, $arr[0]); //Separate off coordinate pairs
$lines = array_slice($arr, ($arr[0] + 2), $arr[1]); //Separate off number of coordinates pairs per stroke
if ($arr[1] == 1) {
$lines[] = ($arr[0] + 2); //If there is only 1 line the end has to be marked
}
$done = 0;
foreach ($lines as $line => $linevalue) {
if ($linevalue > $done) {
$strokes[$line] = array_slice($coords, $done, $linevalue); //Split coordinate pairs into separate strokes
}
$done = $linevalue;
}
//Split X and Y to calculate the maximum and minimum coordinates on both axis
$xmax = 0;
$xmin = 999999;
$ymax = 0;
$ymin = 999999;
foreach ($strokes as $stroke => $xycoords) {
foreach ($xycoords as $xycoord) {
$xyc = explode(' ', $xycoord);
$xy[$stroke]['x'][] = $xyc[0];
if ($xyc[0] > $xmax) $xmax = $xyc[0];
if ($xyc[0] < $xmin) $xmin = $xyc[0];
$xy[$stroke]['y'][] = $xyc[1];
if ($xyc[1] > $ymax) $ymax = $xyc[1];
if ($xyc[1] < $ymin) $ymin = $xyc[1];
}
}
//Add in 10 pixel border to allow for stroke
$xmax += 10;
$xmin -= 10;
$ymax += 10;
$ymin -= 10;
//Calculate the canvas size and offset out anything below the minimum value to trim whitespace from top and left
$xmax -= $xmin;
$ymax -= $ymin;
//Iterate through each stroke and each coordinate pair to make the points on the stroke to build each polyline as a string array
foreach ($xy as $lines => $axis) {
$polylines[$lines] = '<polyline class="sig" points="';
foreach ($xy[$lines]['x'] as $point => $val) {
$x = $xy[$lines]['x'][$point];
$y = $xy[$lines]['y'][$point];
$polylines[$lines] .= ($x - $xmin) . ',' . ($y - $ymin) . ' ';
}
$polylines[$lines] .= '"/>';
}
//Build SVG image string
$image = '
<svg id="sig" data-name="sig" xmlns="http://www.w3.org/2000/svg" width="' . $xmax . '" height="' . $ymax . '" viewBox="0 0 ' . $xmax . ' ' . $ymax . '">
<defs>
<style>
.sig {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 4px;
}
</style>
</defs>
<title>Signature</title>
<g>
';
foreach ($polylines as $polyline) {
$image .= $polyline;
}
$image .= '
</g>
</svg>';
//If file name is supplied write to file
if ($filename) {
try {
$file = fopen($filename, 'w');
fwrite($file, $image);
fclose($file);
return $filename;
} catch (Exception $e) {
return false;
}
} else {
//If file name is not supplied return the SVG image as a string
return $image;
}
} else {
return "Signature is empty";
}
}
Run Code Online (Sandbox Code Playgroud)