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