【发布时间】: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