Last active
January 17, 2019 16:08
-
-
Save FlyingFish07/e84d0bc77d55d0afbeeae7ed232f7809 to your computer and use it in GitHub Desktop.
QRCodeTools, 提供QRCode的生成和解析方式,支持将大文件进行拆分,单个图片中存放多个二维码,对此图片进行解析,并还原原始大文件。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.zyh.qrcode; | |
| import javax.imageio.ImageIO; | |
| import java.awt.image.BufferedImage; | |
| import java.io.*; | |
| import java.awt.*; | |
| public class ImageSplitTest { | |
| public static void main(String[] args) throws IOException { | |
| File file = new File("aoao.jpg"); // I have bear.jpg in my working directory | |
| FileInputStream fis = new FileInputStream(file); | |
| BufferedImage image = ImageIO.read(fis); //reading the image file | |
| int rows = 4; //You should decide the values for rows and cols variables | |
| int cols = 4; | |
| int chunks = rows * cols; | |
| int chunkWidth = image.getWidth() / cols; // determines the chunk width and height | |
| int chunkHeight = image.getHeight() / rows; | |
| int count = 0; | |
| BufferedImage imgs[] = new BufferedImage[chunks]; //Image array to hold image chunks | |
| for (int x = 0; x < rows; x++) { | |
| for (int y = 0; y < cols; y++) { | |
| //Initialize the image array with image chunks | |
| imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType()); | |
| // draws the image chunk | |
| Graphics2D gr = imgs[count++].createGraphics(); | |
| gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null); | |
| gr.dispose(); | |
| } | |
| } | |
| System.out.println("Splitting done"); | |
| //writing mini images into image files | |
| for (int i = 0; i < imgs.length; i++) { | |
| ImageIO.write(imgs[i], "jpg", new File("img" + i + ".jpg")); | |
| } | |
| System.out.println("Mini images created"); | |
| } | |
| } | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.zyh.qrcode; | |
| import java.awt.Graphics2D; | |
| /** | |
| * | |
| */ | |
| import java.awt.image.BufferedImage; | |
| import java.io.File; | |
| import java.io.FileInputStream; | |
| import java.io.IOException; | |
| import java.util.ArrayList; | |
| import java.util.Arrays; | |
| import java.util.Comparator; | |
| import java.util.HashMap; | |
| import javax.imageio.ImageIO; | |
| import org.apache.commons.io.FileUtils; | |
| import com.google.common.io.BaseEncoding; | |
| import com.google.zxing.BinaryBitmap; | |
| import com.google.zxing.DecodeHintType; | |
| 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; | |
| /** | |
| * 利用zxing开源工具生成二维码QRCode | |
| * | |
| * @date 2012-10-26 | |
| * @author xhw | |
| * | |
| */ | |
| public class QRCodeDecoder { | |
| private static final String INPUT_PATH = "rslt"; | |
| private static final int ROWS_PER_PAGE = 2; | |
| private static final int COLUMNS_PER_PAGE = 2; | |
| private static final String OUTPUT_FILE = "output.zip"; | |
| // private static final String QR_CODE_VERSION = "40"; | |
| // private static final int QR_CODE_WIDE = 177 * 4; | |
| // private static final String QR_CODE_ECC_LEVEL = "L"; | |
| // private static final int BYTES_PER_QR_CODE = 2900; | |
| private static int UP_PAD = 60; | |
| private static int RIGHT_PAD = 501; | |
| private static int DOWN_PAD = 110; | |
| private static int LEFT_PAD = 501; | |
| private static final String SEPARATOR_STR = ":::"; | |
| private static final String END_STR = "END-ALL-OK"; | |
| /** | |
| * @param args | |
| * @throws IOException | |
| */ | |
| public static void main(String[] args) throws IOException { | |
| File dir = new File(INPUT_PATH); | |
| File[] allFiles = dir.listFiles(); | |
| Arrays.sort(allFiles, new Comparator<File>() { | |
| public int compare(File o1, File o2) { | |
| return o1.getName().compareTo(o2.getName()); | |
| } | |
| }); | |
| System.out.println("共计"+allFiles.length+"输入文件"); | |
| ArrayList<DecodeStringInfo> decodeStrList = new ArrayList<DecodeStringInfo>(); | |
| String decodeStr= ""; | |
| for(File oneFile : allFiles){ | |
| if(oneFile.getName().startsWith(".")){ | |
| continue; | |
| } | |
| System.out.println("正在处理文件:"+oneFile.getName()); | |
| ArrayList<String> oneFileDecodeStrList = decodeOneFile(oneFile); | |
| for(String oneDecodeStr : oneFileDecodeStrList){ | |
| decodeStr += oneDecodeStr; | |
| DecodeStringInfo dsi = paserDecodeStr(oneDecodeStr); | |
| decodeStrList.add(oneDecodeStr); | |
| } | |
| } | |
| System.out.println("全部完成"); | |
| System.out.println("结果大小:"+decodeStrList.size()); | |
| byte[] contentInBytes = BaseEncoding.base64().decode(decodeStr); | |
| File resultFile = new File(OUTPUT_FILE); | |
| FileUtils.writeByteArrayToFile(resultFile, contentInBytes); | |
| } | |
| private static DecodeStringInfo paserDecodeStr(String oneDecodeStr) { | |
| DecodeStringInfo dsi = new DecodeStringInfo(); | |
| return null; | |
| } | |
| private static ArrayList<String> decodeOneFile(File file) { | |
| ArrayList<String> oneFileRslt = new ArrayList<String>(); | |
| try{ | |
| FileInputStream fis = new FileInputStream(file); | |
| BufferedImage image = removePad(ImageIO.read(fis)); | |
| int rows = ROWS_PER_PAGE; //You should decide the values for rows and cols variables | |
| int cols = COLUMNS_PER_PAGE; | |
| int chunks = rows * cols; | |
| int chunkWidth = image.getWidth() / cols; // determines the chunk width and height | |
| int chunkHeight = image.getHeight() / rows; | |
| int count = 0; | |
| BufferedImage imgs[] = new BufferedImage[chunks]; //Image array to hold image chunks | |
| for (int x = 0; x < rows; x++) { | |
| for (int y = 0; y < cols; y++) { | |
| //Initialize the image array with image chunks | |
| imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType()); | |
| // draws the image chunk | |
| Graphics2D gr = imgs[count++].createGraphics(); | |
| gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null); | |
| gr.dispose(); | |
| } | |
| } | |
| System.out.println("Splitting done"); | |
| //writing mini images into image files | |
| for (int i = 0; i < imgs.length; i++) { | |
| // ImageIO.write(imgs[i], "png", new File("rslt/img" + i + ".png")); | |
| oneFileRslt.add(decode(imgs[i])); | |
| } | |
| System.out.println("one file done..."); | |
| return oneFileRslt; | |
| }catch (Exception ex) { | |
| ex.printStackTrace(); | |
| throw new RuntimeException("解码失败", ex); | |
| } | |
| } | |
| private static BufferedImage removePad(BufferedImage orginalImage) { | |
| int width = orginalImage.getWidth() - LEFT_PAD - RIGHT_PAD; | |
| int height = orginalImage.getHeight() - UP_PAD - DOWN_PAD; | |
| BufferedImage pureImage = new BufferedImage(width, height, orginalImage.getType()); | |
| // draws the image chunk | |
| Graphics2D gr = pureImage.createGraphics(); | |
| gr.drawImage(orginalImage, 0, 0, width, height, LEFT_PAD, UP_PAD, LEFT_PAD + width, UP_PAD + height, null); | |
| gr.dispose(); | |
| return pureImage; | |
| } | |
| /** | |
| * 解析QRCode二维码 | |
| */ | |
| public static String decode(BufferedImage image) { | |
| try { | |
| // image = ImageIO.read(file); | |
| if (image == null) { | |
| System.out.println("Could not decode image"); | |
| } | |
| LuminanceSource source = new BufferedImageLuminanceSource(image); | |
| // int[] pixels = image.getRGB(0, 0, image.getWidth(), image.getHeight(), null, 0, image.getWidth()); | |
| // RGBLuminanceSource source = new RGBLuminanceSource(image.getWidth(), image.getHeight(), pixels); | |
| BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); | |
| Result result; | |
| final HashMap<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>(); | |
| // hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); | |
| // List<BarcodeFormat> formats = new ArrayList<BarcodeFormat>(); | |
| // formats.add(BarcodeFormat.QR_CODE); | |
| // hints.put(DecodeHintType.POSSIBLE_FORMATS, formats); | |
| // hints.put(DecodeHintType.ALLOWED_LENGTHS, 2300); | |
| //// hints.put(DecodeHintType.ERROR_CORRECTION, QR_CODE_ECC_LEVEL); | |
| // //解码设置编码方式为:utf-8 | |
| hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); | |
| hints.put(DecodeHintType.PURE_BARCODE, true); | |
| hints.put(DecodeHintType.TRY_HARDER, true); | |
| QRCodeReader reader = new QRCodeReader(); | |
| result = reader.decode(bitmap, hints); | |
| String resultStr = result.getText(); | |
| System.out.println("解析后内容:" + resultStr); | |
| return resultStr; | |
| } catch(NotFoundException ex){ | |
| System.out.println("未找到二维码"); | |
| return ""; | |
| }catch (Exception ex) { | |
| ex.printStackTrace(); | |
| return ""; | |
| // throw new RuntimeException("解码失败", ex); | |
| } | |
| } | |
| private static class DecodeStringInfo{ | |
| public String index; | |
| public String decodeStr; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.zyh.qrcode; | |
| /** | |
| * | |
| */ | |
| import java.awt.image.BufferedImage; | |
| import java.io.File; | |
| import java.io.IOException; | |
| import java.util.ArrayList; | |
| import java.util.EnumMap; | |
| import java.util.List; | |
| import javax.imageio.ImageIO; | |
| import org.apache.commons.io.FileUtils; | |
| import com.google.common.io.BaseEncoding; | |
| import com.google.zxing.BarcodeFormat; | |
| import com.google.zxing.EncodeHintType; | |
| import com.google.zxing.MultiFormatWriter; | |
| import com.google.zxing.WriterException; | |
| import com.google.zxing.common.BitMatrix; | |
| /** | |
| * 利用zxing开源工具生成二维码QRCode | |
| * | |
| * @date 2012-10-26 | |
| * @author xhw | |
| * | |
| */ | |
| public class QRCodeForMultiple { | |
| private static final int BLACK = 0xFF000000; | |
| private static final int WHITE = 0xFFFFFFFF; | |
| private static final String FILE_NAME = "rslt"+File.separator+"test"; | |
| private static final String SUFFIX = "png"; | |
| private static final String INPUT_FILE = "input.zip"; | |
| private static final int ROWS_PER_PAGE = 2; | |
| private static final int COLUMNS_PER_PAGE = 2; | |
| private static final String QR_CODE_VERSION = "20";//40太大,很难解析成功 | |
| private static final int QR_CODE_WIDE = 57 * 8; | |
| private static final String QR_CODE_ECC_LEVEL = "L"; | |
| private static final int BYTES_PER_QR_CODE = 850; | |
| private static final String SEPARATOR_STR = ":::"; | |
| private static final String END_STR = "END-ALL-OK"; | |
| /** | |
| * @param args | |
| */ | |
| public static void main(String[] args) { | |
| //读取输入文件内容 | |
| byte[] inputData = readInputFile(INPUT_FILE); | |
| //进行Base64编码 | |
| String base64String = BaseEncoding.base64().encode(inputData); | |
| System.out.println("输入文件大小:"+base64String.length()); | |
| List<BitMatrix> bitMatrixList = new ArrayList<BitMatrix>(); | |
| int qrCodeId = 1; | |
| for(int startIndex = 0; startIndex < base64String.length(); startIndex = startIndex + BYTES_PER_QR_CODE){ | |
| int endIndex = startIndex + BYTES_PER_QR_CODE; | |
| if(endIndex > base64String.length()){ | |
| endIndex = base64String.length(); | |
| } | |
| bitMatrixList.add(generateOneQrCode(String.valueOf(qrCodeId)+SEPARATOR_STR+base64String.substring(startIndex, endIndex))); | |
| qrCodeId ++; | |
| } | |
| bitMatrixList.add(generateOneQrCode(String.valueOf(qrCodeId)+SEPARATOR_STR+END_STR)); | |
| System.out.println("需要生成"+bitMatrixList.size()+"个二维码"); | |
| int numberPerPage = ROWS_PER_PAGE * COLUMNS_PER_PAGE; | |
| int needPages = bitMatrixList.size()/numberPerPage + 1; | |
| System.out.println("共需要"+needPages+"个输出文件"); | |
| for(int i=0; i<needPages;i++){ | |
| System.out.println("正在生成第"+i+"个文件"); | |
| List<BitMatrix> bitMatrixListSub = buildSubBitMaxtrixList(bitMatrixList, numberPerPage, i ); | |
| writeToFile(bitMatrixListSub, i); | |
| } | |
| System.out.println("生成完成!"); | |
| } | |
| private static List<BitMatrix> buildSubBitMaxtrixList(List<BitMatrix> bitMatrixList, int numberPerPage, | |
| int pageId) { | |
| List<BitMatrix> bitMatrixListSub = new ArrayList<BitMatrix>(); | |
| int startIndex = numberPerPage * pageId; | |
| int endIndex = numberPerPage * (pageId + 1); | |
| if (endIndex > bitMatrixList.size()) { | |
| endIndex = bitMatrixList.size(); | |
| } | |
| for (int j = startIndex; j < endIndex; j++) { | |
| bitMatrixListSub.add(bitMatrixList.get(j)); | |
| } | |
| return bitMatrixListSub; | |
| } | |
| private static void writeToFile(List<BitMatrix> bitMatrixList, int fileNumber) { | |
| BufferedImage image = toBufferedImage(bitMatrixList); | |
| File file = new File(FILE_NAME+"."+String.format("%04d", fileNumber)+"."+SUFFIX); | |
| try { | |
| ImageIO.write(image, "png", file); | |
| } catch (IOException e) { | |
| System.err.println("生成文件失败"); | |
| e.printStackTrace(); | |
| throw new RuntimeException("生成文件失败"); | |
| } | |
| } | |
| private static BufferedImage toBufferedImage(List<BitMatrix> bitMatrixList) { | |
| int width = bitMatrixList.get(0).getWidth(); | |
| int height = bitMatrixList.get(0).getHeight(); | |
| BufferedImage image = new BufferedImage(COLUMNS_PER_PAGE * width, ROWS_PER_PAGE * height, | |
| BufferedImage.TYPE_INT_ARGB); | |
| for (int i = 0; i < bitMatrixList.size(); i++) { | |
| int row = i / ROWS_PER_PAGE; | |
| int column = i % COLUMNS_PER_PAGE; | |
| BitMatrix matrix = bitMatrixList.get(i); | |
| for (int x = 0; x < width; x++) { | |
| for (int y = 0; y < height; y++) { | |
| image.setRGB(width * column + x, height * row + y, matrix.get(x, y) == true ? BLACK : WHITE); | |
| } | |
| } | |
| } | |
| return image; | |
| } | |
| private static byte[] readInputFile(String inputFile) { | |
| File inFile = new File(inputFile); | |
| byte[] inputDate = null; | |
| try { | |
| inputDate = FileUtils.readFileToByteArray(inFile); | |
| } catch (IOException e) { | |
| System.err.println("读取文件失败"); | |
| e.printStackTrace(); | |
| throw new RuntimeException("读取文件失败"); | |
| } | |
| return inputDate; | |
| } | |
| private static BitMatrix generateOneQrCode(String contents) { | |
| final EnumMap<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>( | |
| EncodeHintType.class); | |
| hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); | |
| hints.put(EncodeHintType.QR_VERSION, QR_CODE_VERSION); | |
| hints.put(EncodeHintType.ERROR_CORRECTION, QR_CODE_ECC_LEVEL); | |
| try { | |
| return new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, QR_CODE_WIDE, QR_CODE_WIDE, hints); | |
| } catch (WriterException e) { | |
| System.err.println("生成二维码报错"); | |
| e.printStackTrace(); | |
| throw new RuntimeException("生成二维码报错",e); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.zyh.qrcode; | |
| /** | |
| * | |
| */ | |
| import java.awt.image.BufferedImage; | |
| import java.io.File; | |
| import java.io.IOException; | |
| import java.util.ArrayList; | |
| import java.util.EnumMap; | |
| import java.util.List; | |
| import javax.imageio.ImageIO; | |
| import org.apache.commons.io.FileUtils; | |
| import com.google.common.io.BaseEncoding; | |
| import com.google.zxing.BarcodeFormat; | |
| import com.google.zxing.EncodeHintType; | |
| import com.google.zxing.MultiFormatWriter; | |
| import com.google.zxing.WriterException; | |
| import com.google.zxing.common.BitMatrix; | |
| /** | |
| * 利用zxing开源工具生成二维码QRCode | |
| * | |
| * @date 2012-10-26 | |
| * @author xhw | |
| * | |
| */ | |
| public class QRCodeForOne { | |
| private static final int BLACK = 0xFF000000; | |
| private static final int WHITE = 0xFFFFFFFF; | |
| private static final String FILE_NAME = "rslt"+File.separator+"test"; | |
| private static final String SUFFIX = "png"; | |
| private static final String INPUT_FILE = "input.zip"; | |
| private static final String QR_CODE_VERSION = "20"; | |
| private static final int QR_CODE_WIDE = 57 * 8; | |
| private static final String QR_CODE_ECC_LEVEL = "L"; | |
| private static final int BYTES_PER_QR_CODE = 850; | |
| /** | |
| * @param args | |
| */ | |
| public static void main(String[] args) { | |
| //读取输入文件内容 | |
| byte[] inputData = readInputFile(INPUT_FILE); | |
| //进行Base64编码 | |
| String base64String = BaseEncoding.base64().encode(inputData); | |
| System.out.println("输入文件大小:"+base64String.length()); | |
| List<BitMatrix> bitMatrixList = new ArrayList<BitMatrix>(); | |
| for(int startIndex = 0; startIndex < base64String.length(); startIndex = startIndex + BYTES_PER_QR_CODE){ | |
| int endIndex = startIndex + BYTES_PER_QR_CODE; | |
| if(endIndex > base64String.length()){ | |
| endIndex = base64String.length(); | |
| } | |
| bitMatrixList.add(generateOneQrCode(base64String.substring(startIndex, endIndex))); | |
| } | |
| System.out.println("需要生成"+bitMatrixList.size()+"个二维码"); | |
| for(int i=0; i<bitMatrixList.size();i++){ | |
| writeToFile(bitMatrixList.get(i), i); | |
| } | |
| } | |
| private static void writeToFile(BitMatrix bitMatrix, int fileNumber) { | |
| BufferedImage image = toBufferedImage(bitMatrix); | |
| File file = new File(FILE_NAME+"."+String.format("%04d", fileNumber)+"."+SUFFIX); | |
| try { | |
| ImageIO.write(image, "png", file); | |
| } catch (IOException e) { | |
| System.err.println("生成文件失败"); | |
| e.printStackTrace(); | |
| throw new RuntimeException("生成文件失败"); | |
| } | |
| } | |
| private static byte[] readInputFile(String inputFile) { | |
| File inFile = new File(inputFile); | |
| byte[] inputDate = null; | |
| try { | |
| inputDate = FileUtils.readFileToByteArray(inFile); | |
| } catch (IOException e) { | |
| System.err.println("读取文件失败"); | |
| e.printStackTrace(); | |
| throw new RuntimeException("读取文件失败"); | |
| } | |
| return inputDate; | |
| } | |
| private static BitMatrix generateOneQrCode(String contents) { | |
| final EnumMap<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>( | |
| EncodeHintType.class); | |
| hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); | |
| hints.put(EncodeHintType.QR_VERSION, QR_CODE_VERSION); | |
| hints.put(EncodeHintType.ERROR_CORRECTION, QR_CODE_ECC_LEVEL); | |
| try { | |
| return new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, QR_CODE_WIDE, QR_CODE_WIDE, hints); | |
| } catch (WriterException e) { | |
| System.err.println("生成二维码报错"); | |
| e.printStackTrace(); | |
| throw new RuntimeException("生成二维码报错",e); | |
| } | |
| } | |
| /** | |
| * 生成二维码内容<br> | |
| * | |
| * @param matrix | |
| * @return | |
| */ | |
| private static BufferedImage toBufferedImage(BitMatrix matrix) { | |
| int width = matrix.getWidth(); | |
| int height = matrix.getHeight(); | |
| BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); | |
| for (int x = 0; x < width; x++) { | |
| for (int y = 0; y < height; y++) { | |
| image.setRGB(x, y, matrix.get(x, y) == true ? BLACK : WHITE); | |
| } | |
| } | |
| return image; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment