当前位置: 首页 > 知识库问答 >
问题:

如何将p:签名值转换为图像(或其他序列化形式)

壤驷华美
2023-03-14

我将在我的站点中使用PrimeFaces的签名标签,但我不知道如何在数据库中以图像的形式存储,或者如果可能的话,以任何其他类型存储。

我只想稍后在数据表中显示它,以便管理员可以管理和验证这些签名的真实性。

共有3个答案

常源
2023-03-14

p的值:当您决定发送到数据库时,签名作为字符串值存储在数据库中,例如{“行”:[[[308.4113.86],[284.4117.86],[233.4125.86],[168.4135.86],[116.4143.86],[89.4145.86],[90.4145.86],[106.4141.86],[144.4135.86],[180.4131.86],[184.4131.86],[184.4131.86],[177.4131.86]}

权承
2023-03-14

我能够将签名转换为字节数组,并使用以下代码将其加密存储在我的内容存储库(filenet)中:

/**
     * A point along a line within a signature.
     */
    private static class Point {

        private int x;
        private int y;

        public Point(float x, float y) {
            this.x = Math.round(x);
            this.y = Math.round(y);
        }
    }

    public static void generateSignature(String jsonEncoding, OutputStream output) throws IOException {
        output.write(redrawSignature(extractSignature(jsonEncoding)));
        output.close();
    }

    /**
     * Extract the signature lines and points from the JSON encoding.
     * 
     * @param jsonEncoding
     *            the JSON representation of the signature
     * @return the retrieved lines and points
     */
    private static List<List<Point>> extractSignature(String jsonEncoding) {
        List<List<Point>> lines = new ArrayList<List<Point>>();
        Matcher lineMatcher = Pattern.compile("(\\[(?:,?\\[-?[\\d\\.]+,-?[\\d\\.]+\\])+\\])").matcher(jsonEncoding);
        while (lineMatcher.find()) {
            Matcher pointMatcher = Pattern.compile("\\[(-?[\\d\\.]+),(-?[\\d\\.]+)\\]").matcher(lineMatcher.group(1));
            List<Point> line = new ArrayList<Point>();
            lines.add(line);
            while (pointMatcher.find()) {
                line.add(new Point(Float.parseFloat(pointMatcher.group(1)), Float.parseFloat(pointMatcher.group(2))));
            }
        }
        return lines;
    }

    /**
     * Redraw the signature from its lines definition.
     * 
     * @param lines
     *            the individual lines in the signature
     * @return the corresponding signature image
     * @throws IOException
     *             if a problem generating the signature
     */
    private static byte[] redrawSignature(List<List<Point>> lines) throws IOException {
        BufferedImage signature = new BufferedImage(SIGNATURE_WIDTH, SIGNATURE_HEIGHT, BufferedImage.TYPE_BYTE_GRAY);
        Graphics2D g = (Graphics2D) signature.getGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, signature.getWidth(), signature.getHeight());
        g.setColor(Color.BLACK);
        g.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Point lastPoint = null;
        for (List<Point> line : lines) {
            for (Point point : line) {
                if (lastPoint != null) {
                    g.drawLine(lastPoint.x, lastPoint.y, point.x, point.y);
                }
                lastPoint = point;
            }
            lastPoint = null;
        }
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        ImageIO.write(signature, IMAGE_FORMAT, output);
        return output.toByteArray();
    }
皇甫伟彦
2023-03-14

只需查看PrimeFaces showcase中的签名即可。签名值绑定到字符串,因此您可以简单地将签名作为字符串存储在数据库中。稍后,您可以简单地使用存储的字符串以及设置为“真”的属性来显示签名。这正是展示中展示的内容。

您的签名字符串值如下所示:

{"lines":[[[81,75],[81,78],[81,80],[81,84],[83,87],...]]}

如果您真的想将其存储为图像而不是字符串,那么有几个选项。

由于字符串基本上是一个带有“lines”数组的JSON对象,每行都有坐标,因此您可以简单地将其转换为SVG。您所需要做的就是创建一些路径。粗略实施:

public String toSvg(String signature, int width, int height) {
  List<String> paths = new ArrayList<>();
  try (JsonReader jsonReader = Json.createReader(new StringReader(signature))) {
    JsonObject jsonObject = jsonReader.readObject();
    JsonArray jsonArray = jsonObject.getJsonArray("lines");
    jsonArray.forEach(line -> paths.add(toSvgPath((JsonArray) line)));
  }
  StringBuilder sb = new StringBuilder();
  sb.append(String.format("<svg width=\"%d\" height=\"%d\" xmlns=\"http://www.w3.org/2000/svg\">\n", width, height));
  paths.forEach(sb::append);
  sb.append("</svg>");
  return sb.toString();
}


private String toSvgPath(JsonArray line) {
  StringBuilder sb = new StringBuilder("<path d=\"");
  for (int i = 0; i < line.size(); i++) {
    JsonArray coords = (JsonArray) line.getJsonArray(i);
    sb.append(String.format("%s%d %d ", (i == 0 ? "M" : "L"), coords.getInt(0), coords.getInt(1)));
  }
  sb.append("\" stroke=\"black\" fill=\"transparent\"/>\n");
  return sb.toString();
}

但是,由于可以很容易地从JSON对象创建SVG,您可能只想存储JSON对象,并在需要呈现签名时创建SVG。

另请参见:

  • 如何将字符串转换为JsonObject
  • 请解释SVG路径命令和坐标

签名具有一个属性,该属性将PNG图像作为base64编码的数据写入提供的属性:

<p:signature id="signature"
             base64Value="#{myBean.signature}">

这将为您提供如下URL:

data:image/png;base64,iVBORw0KGgoAAAANSU...

在bean中,只需从URL获取数据:

private static final String URL_DATA_PNG_BASE64_PREFIX = "data:image/png;base64,";

..

String encoded = signatureUrl.substring(URL_DATA_PNG_BASE64_PREFIX.length());
byte[] decoded = Base64.getDecoder().decode(encoded);

您可以选择将其另存为文件:

Path path = Paths.get("path/to/your/image.png");
Files.write(path, decoded);

另请参见:

  • 在Java中解码Base64数据
  • https://primefaces.github.io/primefaces/8_0/#/components/signature?id=convert-到二进制
 类似资料:
  • 我的目标是使图像圆形并显示它。如果图像是方形的,那么我可以通过简单地使用CSS的属性将其转换为圆形。但是当图像是矩形时,使用这个CSS属性会给我椭圆形的图像。 剪辑的部分是不可见的,但仍然存在。所以即使现在我也在尝试使用属性,它给我椭圆形图像,右侧和左侧被剪辑。 我有什么办法可以解决这个问题吗?

  • 问题内容: 这个下课 需要转换为 我尝试将对象手动传递给将变量设置为字典并返回字典的函数。但是,我希望有一种更好的方法来实现这一目标。 问题答案: 在Swift 4中,您可以从类型继承。

  • 假设我有一个表customer(int id,类型varchar,首选项jsonb)。类型可以是、等。根据列类型值,首选项JSON结构将有所不同。 在从数据库加载客户记录时,如果type=regular我希望将其转换为对象类型,如果type=premium我希望将其转换为对象类型。 我已经阅读了几篇关于使用JOOQ JSON转换器/绑定的教程。但是它们是一对一映射,不是基于条件的(取决于另一个列值

  • 我目前正在从事一个股票市场项目,教学生如何与股票市场互动。我现在正在研究的一个问题围绕着效率和记忆力的问题。我在Adobe illustrator中制作了所有2D图标(例如设置图标,投资组合图标等),我将这些文件导出为png文件,并将它们放入我的程序中。我目前使用 JavaFX,JavaFX 的一个功能是所谓的图像视图,这是一种处理图像打开和查看的方法。 假设用户想在游戏中按下设置图标,当用户悬停

  • 我将图像转换为整数列表。例如。[226,137,125,226,137,125,223,137,133,223,136,128、226、138、120、226、129、116、228、138、123、227、134、124、227、140、127、225、136、119、228、135、126、225、134、121、223、130、108、226、139、119、123、120、221、129、

  • 问题内容: 我正在尝试使用以下代码将Icon()转换为Image(): 问题是,函数在上抛出。 对于记录,该值为默认图标(通过获取) 以下是引发异常的详细信息: 如果您需要更多详细信息,请告诉我,我将编辑我的信息以添加它们。 谢谢! 问题答案: 刚刚找到了一个代码段,如果您想更频繁地包装那些表现不佳的LAF提供的图标,可能会有所帮助: 要在您的代码段中使用,只需传递任意组件: