【问题标题】:How to improve quality of signature image embedded in pdf如何提高嵌入在 pdf 中的签名图像的质量
【发布时间】:2019-08-16 18:09:24
【问题描述】:

我正在开发一个将签名嵌入到 pdf 文档的 Web 应用程序。我正在使用以下库Zetakey Sign & Send。从签名板签名是使用以下方法捕获的:

var dataURL = canvas.toDataURL("image/png",1);

而在服务器端(签名字符串的第一次Base64解码):

    public String createSignature(String mySignature,int width,int height) throws IOException {
    String filePath = SIGNATURE_PATH +"signature_" + new Date().getTime() + ".png";
    byte[] imageByteArray = decodeImage(mySignature);
    try(FileOutputStream imageOutFile = new FileOutputStream(filePath)){
        imageOutFile.write(imageByteArray);
    }
    try {
        BufferedImage image = ImageIO.read(new File(filePath));
        image = scaleImage(image, width, height);
        ImageIO.write(image, "png", new File(filePath));
        for(Iterator<ImageWriter> iw = ImageIO.getImageWritersByFormatName("png"); iw.hasNext();) {
            ImageWriter writer = iw.next();
            ImageWriteParam writeParam = writer.getDefaultWriteParam();
            ImageTypeSpecifier typeSpecifier = ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
            IIOMetadata metadata = writer.getDefaultImageMetadata(typeSpecifier, writeParam);
            if(metadata.isReadOnly() || !metadata.isStandardMetadataFormatSupported()) {
                continue;
            }
            setDPI(metadata,500,width,height);
            try (ImageOutputStream stream = ImageIO.createImageOutputStream(new FileOutputStream(filePath))){
                writer.setOutput(stream);
                writer.write(metadata, new IIOImage(image, null, metadata), writeParam);
            }
            break;

        }
    } catch (IOException e) {
          logger.error(e.getMessage());
    }

    return filePath;
}

private static void setDPI(IIOMetadata metadata, int value, int width, int height) throws IIOInvalidTreeException {
    double dotsPerMilli = value/(INCH_TO_CM*10);

    IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
    horiz.setAttribute(VAL, Double.toString(dotsPerMilli));
    IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
    vert.setAttribute(VAL, Double.toString(dotsPerMilli));

    IIOMetadataNode horizScreenSize = new IIOMetadataNode("HorizontalScreenSize");
    horizScreenSize.setAttribute(VAL, Integer.toString(width));

    IIOMetadataNode vertScreenSize = new IIOMetadataNode("VerticalScreenSize");
    vertScreenSize.setAttribute(VAL, Integer.toString(height));

    IIOMetadataNode dim = new IIOMetadataNode("Dimension");
    dim.appendChild(horiz);
    dim.appendChild(vert);
    dim.appendChild(horizScreenSize);
    dim.appendChild(vertScreenSize);

    IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
    root.appendChild(dim);

    metadata.mergeTree("javax_imageio_1.0", root);
}

public static BufferedImage scaleImage(BufferedImage original, int width, int height){
    BufferedImage scaled = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    AffineTransform at = new AffineTransform();
    at.scale(((float)width)/original.getWidth(), ((float)height)/original.getHeight());
    Map<RenderingHints.Key, Object> map = new HashMap<>();
    map.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    map.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    RenderingHints hints = new RenderingHints(map);
    AffineTransformOp scaleOp = new AffineTransformOp(at, hints);
    scaled = scaleOp.filter(original, scaled);
    return scaled;
}

但是,即使尝试 500 DPI,打印在 pdf 上的签名图像的质量也不能令人满意。我错过了什么吗?

【问题讨论】:

  • 图片本身不满意吗?
  • 为什么要缩放图像?您是否尝试按原样添加图像
  • 您可以使用sharpening kernel 来增强图像
  • @iffy6 ,图像本身令人满意。
  • @karthick,我们无法按原样添加图像。它太大了 - 我们为用户提供了 320x200 像素的签名板,因为在较小的画布中用户很难绘制签名。如果按原样添加,图像质量非常好。

标签: java image pdf image-processing itext


【解决方案1】:

因此,使用 ZetaKey 的现场演示,签名捕获返回了可接受的质量 PNG 图像...

考虑以下几点:

  • 我可以只使用未更改的原始图像吗?
  • 如果不是,我可以更改我的转换顺序吗? (DPI -> 比例与比例 -> DPI)
  • 我可以放弃缩放吗? (通常是分辨率下降的原因)

我怀疑您正在丢失图像分辨率,因为您在缩放图像后调整 DPI。

缩放和 DPI 的影响:

Effects of Image Transformations (DPI)

摘录:(不直接相关,但可以深入了解问题)

现在假设您想使用普通胶印机打印图像,该胶印机最多可以打印 300dpi 图像。假设您尝试以英寸为单位的原始图像尺寸精确打印它。印刷机每英寸需要 300 个点才能做好工作。您提供的图像每英寸只有 72 个点,因此印刷机(或更准确地说,为印刷机准备印版的软件)必须弥补缺失的点。结果会模糊或嘈杂,因为软件会创造性地添加许多“过渡”点来填补缺失的空白。

【讨论】:

  • E.米勒,我将更改转换顺序并在周一报告结果
  • 我已经尝试了所有的建议,包括锐化滤镜。尚不确定它们是否产生了积极影响。我已经部署了代码,让我的 QA 回复我他们的看法。
  • @SubhenduMahanta 如果没有任何效果,您可能希望转换为基于矢量的图像而不是基于像素的图像。矢量图像缩放而没有质量损失。见:howtogeek.com/howto/32597/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多