package com.ns.utils; import java.awt.image.BufferedImage; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDResources; import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObject; import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage; import com.ns.service.QRCodeDecoder; public class QRCodePdModelUtil { @SuppressWarnings("unchecked") public static Map<String, String> scanQRCode(String dir, String fileName, String textKey) { Map<String, String> map = new HashMap<String, String>(); List<PDPage> pages = null; BufferedImage qrCodeImg = null; String qrCode = null; PDDocument pdfDoc = null; try { Path docPath = Paths.get(dir.concat(fileName)); pdfDoc = PDDocument.load(docPath.toFile()); QRCodeDecoder decoder = new QRCodeDecoder(); pages = pdfDoc.getDocumentCatalog().getAllPages(); int dpi = 0; int dpiEffective = 0; int dpiLow = 0; for (PDPage page : pages) { try { if (null == qrCode) { qrCodeImg = page.convertToImage(BufferedImage.TYPE_BYTE_GRAY, 100); qrCode = decoder.getCompressedQRCode(qrCodeImg); } if (null == qrCode) { dpi = detectPageDPI(page); dpiEffective = dpi; dpiLow = dpi - 5; for (; dpiLow < dpiEffective; dpiEffective--) { qrCodeImg = page.convertToImage(BufferedImage.TYPE_BYTE_GRAY, dpiEffective); qrCode = decoder.getCode(qrCodeImg); if (null != qrCode) { break; } } } if (null == qrCode) { qrCodeImg = page.convertToImage(BufferedImage.TYPE_BYTE_GRAY, 400); qrCode = decoder.getCompressedQRCode(qrCodeImg); } System.out.println("Code:::" + qrCode); if (null != qrCode) { map.put("DPI", Integer.toString(dpi)); map.put(textKey, qrCode); return map; } } catch (Exception e) { System.out.println(e.getMessage()); } finally { qrCodeImg = null; qrCode = null; } } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { if (null != pdfDoc) { try { pdfDoc.close(); } catch (IOException e) { e.printStackTrace(); } } pages = null; } return null; } private static int detectPageDPI(PDPage page) { PDResources res = page.getResources(); Collection<PDXObject> xObjects = res.getXObjects().values(); int imgHeight = 0; for (PDXObject xObject : xObjects) { if (xObject instanceof PDXObjectImage) { imgHeight = ((PDXObjectImage) xObject).getHeight(); } } float pageHeight = page.getMediaBox().getHeight() / 72; int dpi = (int) (imgHeight / pageHeight); if (200 > dpi) { dpi = 200; } if (300 < dpi) { dpi = 300; } return dpi; } }
package com.ns.service; import java.awt.RenderingHints; import java.awt.RenderingHints.Key; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ConvolveOp; import java.awt.image.Kernel; import java.awt.image.RasterFormatException; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Service; import com.google.zxing.BinaryBitmap; import com.google.zxing.ChecksumException; import com.google.zxing.FormatException; import com.google.zxing.LuminanceSource; import com.google.zxing.NotFoundException; import com.google.zxing.Result; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.QRCodeReader; @Service public class QRCodeDecoder { public String getCode(BufferedImage image) { String code = null; try { // vertical bottom scan BufferedImage procImage = image.getSubimage(0, image.getHeight() / 2, image.getWidth(), image.getHeight() / 2 - 20); code = decode(procImage); } catch (RasterFormatException e) { // continue } return code; } public String getCompressedQRCode(BufferedImage image) { String code = null; try { // vertical bottom scan BufferedImage procImage = image.getSubimage(150, image.getHeight() / 2, image.getWidth() - 150, image.getHeight() / 2 - 200); code = decode(procImage); } catch (RasterFormatException e) { // continue } return code; } public String decode(BufferedImage image) { RenderingHints hints = getRenderingHints(); float[] kernelData = null; BufferedImageOp op = null; BufferedImage procImage = null; LuminanceSource source = null; BinaryBitmap bitmap = null; QRCodeReader reader = new QRCodeReader(); Result result = null; String code = null; for (int denom = 10; denom <= 50; denom += 10) { try { procImage = image; float factor = (1.0f / ((float) denom)); kernelData = getKernelData(factor); op = new ConvolveOp(new Kernel(4, 4, kernelData), ConvolveOp.EDGE_NO_OP, hints); source = new BufferedImageLuminanceSource(op.filter(procImage, null)); bitmap = new BinaryBitmap(new HybridBinarizer(source)); result = reader.decode(bitmap); code = result.getText(); break; } catch (NotFoundException e) { // continue } catch (ChecksumException e) { // continue } catch (FormatException e) { // continue } finally { hints = null; kernelData = null; op = null; source = null; bitmap = null; procImage = null; result = null; } } return code; } protected RenderingHints getRenderingHints() { Map<Key, Object> map = new HashMap<Key, Object>(); 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); return hints; } protected float[] getKernelData(float data) { return new float[] { data, data, data, data, data, data, data, data, data, data, data, data, data, data, data, data }; } }