如何在PHP文件中捕获签名板图像并输出到HTML文件(如收据),然后将页面存储为JPEG或PDF

时间:2019-07-03 21:13:11

标签: javascript php html json

我正在使用Thomas J. Bradley的签名板将客户的签名应用于收据页面,但是他的教程尚未完成,并且只剩下一个带有签名的PHP页面,而在下一页中没有有关如何应用该签名的描述。它只是在输出页面上停止,仅带有签名图像本身。我想将其应用到我已经在产品信息下构建的收据HTML页面中,然后将页面的屏幕截图作为电子邮件发送,以将收据基本上存储在我的计算机上。这就是我的所在。

签名页

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=windows-1252" http-equiv="Content-Type" />
<meta name="robots" content="noindex" />
<meta name="googlebot" content="noindex" />
<meta name="googlebot-news" content="noindex" />
<title>Signature</title>
<style type="text/css">
.disclaimerific {
    font-family: Arial, Helvetica, sans-serif;
}
.auto-style10 {
    text-align: left;
}
</style>
<link href="assets/jquery.signaturepad.css" rel="stylesheet">
<!--[if lt IE 9]><script src="assets/flashcanvas.js"></script><![endif]-->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
   <link rel="stylesheet" type="text/css" href="css/default.css" /> 
        <link rel="stylesheet" type="text/css" href="css/component.css" />


        <script src="js/modernizr.custom.js"></script>
</head>

<body style="background-color: #DDDDDD">

<table align="center" cellpadding="0" cellspacing="0" style="width: 799px">
    <tr>
        <td>
        <p style="margin-top: 0; margin-bottom: 0">
        <img alt="" height="27" src="http://www.themidaslegacy.com/images2/headerml.jpg" width="800" /></p>
        </td>
    </tr>
<tr>
    <td style="background-color: #FFFFFF">
        <div style="text-align: center">
            <div align="center">
                <table border="0" width="100%" cellspacing="10" cellpadding="10">
                    <tr>
                        <td>
                        <div class="auto-style10" style="text-align:center;">
                            <font size="6" color="#CC0000" face="Impact">Please sign below. </font>
                        </div>
                        <p class="auto-style10" style="text-align:center;margin-bottom:0px;"><font face="Arial">***After you submit your signature it will be applied to your receipt on the next page.*** <br>

                        </td>
                    </tr>
                </table>
            </div>
        </div>
        <!-- Signature Table Box -->
                <div style="width:450px; height:auto;  margin: 0px auto 50px; auto; padding:20px; color:black;" >

                     <form method="post" action="capture_signature.php" class="sigPad">

                        <p class="drawItDesc">Draw your signature</p>

                        <div class="sig sigWrapper">
                          <canvas class="pad" width="400"></canvas>

                          <input type="hidden" name="output" class="output">
                        </div>
                        <br>
                        <div style="width:100%;">
                            <style>

                                </style>
                            <table style="width: 100%;text-align: center;">
                                <tr>
                                    <td style="width: 50%;">
                                     <div id="submit" >
                                        <button id="btn-accept" style="width: 100%;color:white;" href="" type="submit" class="button1"><p style="font-size: 14px;">Accept Agreement.</p></button>
                                    </div>
                                    </td>
                                    <td style="width: 50%;">
                                    <div id="clear" >
                                        <button style="width: 100%;" href="" name="clear" type="clear" class="clearButton"><p style="font-size: 14px;">Clear Signature</p></button>
                                    </div>
                                    </td>
                                </tr>
                            </table>
                        </div>
                        <!-- <div style="clear:both;"></div> -->
                      </form>

                </div>
                        <script src="assets/flashcanvas.js"></script>
                         <script src="assets/jquery.signaturepad.js"></script>
                          <script src="assets/json2.min.js"></script>
                          <script src="assets/functions.js"></script>

        <!-- End Signature Table Box -->

    </td>
</tr>
    <tr>
      <td style="background-color: #dddddd">
        <p style="margin-top: 0; margin-bottom: 0">&nbsp;</td>
  </tr>
    <tr>
      <td style="background-color: #dddddd; font-family:Arial, Helvetica, sans-serif; font-size:9px; color:#666">
        <div align="center">
        <p style="margin-top: 0; margin-bottom: 0">&nbsp;<img alt="" height="36" src="../images2/contactfooter.jpg" width="557" /><br />
        <br />
      </div></td>
  </tr>
    <tr>
      <td style="background-color: #dddddd; font-family:Arial, Helvetica, sans-serif; font-size:9px; color:#666"><div align="center">
        <p style="margin-top: 0; margin-bottom: 0">&copy; Copyright TML Group, LLC.<br />
        </div></td>
  </tr>
    <tr>
      <td height="2" style="background-color: #dddddd"></span></td>
  </tr>
</table>
        <div align="center" style="width:750px; color:#666666"  >
            <p style="margin-top: 0; margin-bottom: 0"></div>
<p style="margin-top: 0; margin-bottom: 0"></p>
        </td>
    </tr>
<tr>
        <td style="text-align: center"></tr>
</td>
    </tr>
    <tr>
        <td style="text-align: center">
        <p style="margin-top: 0; margin-bottom: 0"></p>
        </td>
</tr>
</table>
<script type="text/javascript" src="https://ra128.infusionsoft.com/app/webTracking/getTrackingCode?trackingId=6a323c394c72471d0866a90788baeed5"></script>

</body>

</html>

签名到图片页面

<?php
/**
 *  Signature to Image: A supplemental script for Signature Pad that
 *  generates an image of the signature’s JSON output server-side using PHP.
 *
 *  @project ca.thomasjbradley.applications.signaturetoimage
 *  @author Thomas J Bradley <hey@thomasjbradley.ca>
 *  @link http://thomasjbradley.ca/lab/signature-to-image
 *  @link http://github.com/thomasjbradley/signature-to-image
 *  @copyright Copyright MMXI–, Thomas J Bradley
 *  @license New BSD License
 *  @version 1.1.0
 */

/**
 *  Accepts a signature created by signature pad in Json format
 *  Converts it to an image resource
 *  The image resource can then be changed into png, jpg whatever PHP GD supports
 *
 *  To create a nicely anti-aliased graphic the signature is drawn 12 times it's original size then shrunken
 *
 *  @param string|array $json
 *  @param array $options OPTIONAL; the options for image creation
 *    imageSize => array(width, height)
 *    bgColour => array(red, green, blue) | transparent
 *    penWidth => int
 *    penColour => array(red, green, blue)
 *    drawMultiplier => int
 *
 *  @return object
 */
function sigJsonToImage ($json, $options = array()) {
  $defaultOptions = array(
    'imageSize' => array(410, 155)
    ,'bgColour' => array(0xff, 0xff, 0xff)
    ,'penWidth' => 2
    ,'penColour' => array(0x14, 0x53, 0x94)
    ,'drawMultiplier'=> 12
  );

  $options = array_merge($defaultOptions, $options);

  $img = imagecreatetruecolor($options['imageSize'][0] * $options['drawMultiplier'], $options['imageSize'][1] * $options['drawMultiplier']);

  if ($options['bgColour'] == 'transparent') {
    imagesavealpha($img, true);
    $bg = imagecolorallocatealpha($img, 0, 0, 0, 127);
  } else {
    $bg = imagecolorallocate($img, $options['bgColour'][0], $options['bgColour'][1], $options['bgColour'][2]);
  }

  $pen = imagecolorallocate($img, $options['penColour'][0], $options['penColour'][1], $options['penColour'][2]);
  imagefill($img, 0, 0, $bg);

  if (is_string($json))
    $json = json_decode(stripslashes($json));

  foreach ($json as $v)
    drawThickLine($img, $v->lx * $options['drawMultiplier'], $v->ly * $options['drawMultiplier'], $v->mx * $options['drawMultiplier'], $v->my * $options['drawMultiplier'], $pen, $options['penWidth'] * ($options['drawMultiplier'] / 2));

  $imgDest = imagecreatetruecolor($options['imageSize'][0], $options['imageSize'][1]);

  if ($options['bgColour'] == 'transparent') {
    imagealphablending($imgDest, false);
    imagesavealpha($imgDest, true);
  }

  imagecopyresampled($imgDest, $img, 0, 0, 0, 0, $options['imageSize'][0], $options['imageSize'][0], $options['imageSize'][0] * $options['drawMultiplier'], $options['imageSize'][0] * $options['drawMultiplier']);
  imagedestroy($img);

  return $imgDest;
}

/**
 *  Draws a thick line
 *  Changing the thickness of a line using imagesetthickness doesn't produce as nice of result
 *
 *  @param object $img
 *  @param int $startX
 *  @param int $startY
 *  @param int $endX
 *  @param int $endY
 *  @param object $colour
 *  @param int $thickness
 *
 *  @return void
 */
function drawThickLine ($img, $startX, $startY, $endX, $endY, $colour, $thickness) {
  $angle = (atan2(($startY - $endY), ($endX - $startX)));

  $dist_x = $thickness * (sin($angle));
  $dist_y = $thickness * (cos($angle));

  $p1x = ceil(($startX + $dist_x));
  $p1y = ceil(($startY + $dist_y));
  $p2x = ceil(($endX + $dist_x));
  $p2y = ceil(($endY + $dist_y));
  $p3x = ceil(($endX - $dist_x));
  $p3y = ceil(($endY - $dist_y));
  $p4x = ceil(($startX - $dist_x));
  $p4y = ceil(($startY - $dist_y));

  $array = array(0=>$p1x, $p1y, $p2x, $p2y, $p3x, $p3y, $p4x, $p4y);
  imagefilledpolygon($img, $array, (count($array)/2), $colour);
}

捕获图像页面的最终结果

<?php
require_once 'signature-to-image.php';
$json = $_POST['output'];
$img = sigJsonToImage($json);
imagepng($img, 'signature.png');
header('Content-Type: image/png');
imagepng($img);
imagedestroy($img);

这是起始页 https://www.protml.com/tmr/sig-confirm.html

这是结果结束的地方 https://www.protml.com/tmr/capture_signature.php

1 个答案:

答案 0 :(得分:0)

如果您想使用其他HTTP请求将此图像加载到目标页面中(意味着您想使用<img src="http://hostname/somescript.php">嵌入图像),则需要将数据传递到此somescript.php 。现在,根据用户在输入板上书写的多少,实际创建的多少“黑色像素”,JSON数据可能会变得非常大-可能太大而无法在查询字符串中放入GET请求。而且,由于无法结合使用POST和<img src="...">来轻松加载图像,因此将其放入会话中可能是最有意义的。 (在处理客户数据的情况下,我认为您可能已经在使用会话了。)

因此,在接收POST数据的脚本(与/tmr/capture_signature.php不同的脚本)中,将其放入会话中,

$_SESSION['sigpaddata'] = $_POST['output'];

,然后在生成图像(/tmr/capture_signature.php)的脚本中,从那里读回它(不要忘记在该脚本中再次接听会话)

$json = $_SESSION['sigpaddata'];

然后使用

将图像嵌入到目标页面上
<img src="/tmr/capture_signature.php">

现在,如果用户在多个选项卡中打开此脚本的多个实例,则可能会导致麻烦,从而为多个收据创建签名。如果是现实情况,则可以向表单添加一个随机值,将JSON数据存储在该随机键($_SESSION['sigpaddata'][$_POST['randkey']] = …下的会话中–您必须检查JS部分是否自动发送所有表单数据,或者是否也需要修改以提交此附加值),然后将相同的随机密钥传递给图像生成脚本(<img src="/tmr/capture_signature.php?randkey=…">),以便依次再次从会话中获取正确的值($_SESSION['sigpaddata'][$_GET['randkey']]


另一种不需要额外的HTTP请求的方法-从而减少了将必要的数据获取到图像创建代码的麻烦-将图像“内联”输出到目标页面Data URI和base64编码的图像数据。这涉及到输出缓冲以捕获imagepng的输出(无论如何,您目前正在将图像保存到文件中,因此理论上您可以在此之后立即从该位置读取它-但随后需要使用signature.png每次由多个客户发出的多个并发请求显然会导致麻烦。)

require_once 'signature-to-image.php';
$json = $_POST['output'];
$img = sigJsonToImage($json);
ob_start(); // start output buffer
imagepng($img); // output image data to buffer
imagedestroy($img);
// create Data URI for a PNG image, using the binary image
// data captured from the output buffer
$dataURI = 'data:image/png;base64,'.base64_encode(ob_get_clean());

// echo HTML img element using that Data URI, somewhere on the page
echo '<img src="'.$dataURI.'">';

这可以直接在您根据前一页发送的表单数据生成的响应页面中使用。由于不需要额外的HTTP请求,因此POST数据可直接在此处使用,无需使用会话或类似方法传递到其他图像生成脚本。