简体   繁体   中英

How to improve quality of signature image embedded in pdf

I am working on an web application to embed signature to pdf document. I am using following library Zetakey Sign & Send .From the signature pad signature is captured using:

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

And in the server side(first Base64 decoding of signature string):

    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;
}

But the quality of signature image printed on pdf is not at all satisfactory even after attempting 500 DPI.Am I missing something?

So, using the ZetaKey's live-demo, the signature capture returned an acceptable quality PNG image...

Consider the following things:

  • Can I just use the original, unaltered image?
  • If not, can I change the order of my transformations? (DPI -> Scale Vs Scale -> DPI )
  • Can I forgo scaling? (often the cause of resolution loss)

I suspect that you are losing image resolution because you're adjusting DPI after you scale the image.

Effects of Scaling and DPI:

Effects of Image Transformations (DPI)

Excerpt: (not directly related, but may give insight into problem)

Now suppose you want to print your image using a regular offset press, which can print up to 300dpi images. Suppose you try to print it exactly at the original image dimension in inches. The press needs 300 dots for every inch to do a good job. The image you are supplying has only 72 dots for every inch, so the press (or more accurately, the software that prepares the plates for the press) has to make up the missing dots. The result will be blurry or noisy because there will be a lot of "transitional" dots that the software will creatively add to fill the missing gaps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM