/* * Copyright 2012 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.zxing.pdf417.encoder; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.Writer; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import java.util.EnumMap; import java.util.Map; /** * @author Jacob Haynes * @author qwandor@google.com (Andrew Walbran) */ public final class PDF417Writer implements Writer { @Override public BitMatrix encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType,?> hints) throws WriterException { if (format != BarcodeFormat.PDF_417) { throw new IllegalArgumentException("Can only encode PDF_417, but got " + format); } PDF417 encoder = new PDF417(); if (hints != null) { if (hints.containsKey(EncodeHintType.PDF417_COMPACT)) { encoder.setCompact((Boolean) hints.get(EncodeHintType.PDF417_COMPACT)); } if (hints.containsKey(EncodeHintType.PDF417_COMPACTION)) { encoder.setCompaction((Compaction) hints.get(EncodeHintType.PDF417_COMPACTION)); } if (hints.containsKey(EncodeHintType.PDF417_DIMENSIONS)) { Dimensions dimensions = (Dimensions) hints.get(EncodeHintType.PDF417_DIMENSIONS); encoder.setDimensions(dimensions.getMaxCols(), dimensions.getMinCols(), dimensions.getMaxRows(), dimensions.getMinRows()); } } return bitMatrixFromEncoder(encoder, contents, width, height); } @Override public BitMatrix encode(String contents, BarcodeFormat format, int width, int height) throws WriterException { return encode(contents, format, width, height, null); } /** * @deprecated Use {@link #encode(String, BarcodeFormat, int, int, Map)} instead, with hints to * specify the encoding options. */ @Deprecated public BitMatrix encode(String contents, BarcodeFormat format, boolean compact, int width, int height, int minCols, int maxCols, int minRows, int maxRows, Compaction compaction) throws WriterException { Map<EncodeHintType, Object> hints = new EnumMap<EncodeHintType,Object>(EncodeHintType.class); hints.put(EncodeHintType.PDF417_COMPACT, compact); hints.put(EncodeHintType.PDF417_COMPACTION, compaction); hints.put(EncodeHintType.PDF417_DIMENSIONS, new Dimensions(minCols, maxCols, minRows, maxRows)); return encode(contents, format, width, height, hints); } /** * Takes encoder, accounts for width/height, and retrieves bit matrix */ private static BitMatrix bitMatrixFromEncoder(PDF417 encoder, String contents, int width, int height) throws WriterException { int errorCorrectionLevel = 2; encoder.generateBarcodeLogic(contents, errorCorrectionLevel); int lineThickness = 2; int aspectRatio = 4; byte[][] originalScale = encoder.getBarcodeMatrix().getScaledMatrix(lineThickness, aspectRatio * lineThickness); boolean rotated = false; if ((height > width) ^ (originalScale[0].length < originalScale.length)) { originalScale = rotateArray(originalScale); rotated = true; } int scaleX = width / originalScale[0].length; int scaleY = height / originalScale.length; int scale; if (scaleX < scaleY) { scale = scaleX; } else { scale = scaleY; } if (scale > 1) { byte[][] scaledMatrix = encoder.getBarcodeMatrix().getScaledMatrix(scale * lineThickness, scale * aspectRatio * lineThickness); if (rotated) { scaledMatrix = rotateArray(scaledMatrix); } return bitMatrixFrombitArray(scaledMatrix); } return bitMatrixFrombitArray(originalScale); } /** * This takes an array holding the values of the PDF 417 * * @param input a byte array of information with 0 is black, and 1 is white * @return BitMatrix of the input */ private static BitMatrix bitMatrixFrombitArray(byte[][] input) { // Creates a small whitespace border around the barcode int whiteSpace = 30; // Creates the bitmatrix with extra space for whitespace BitMatrix output = new BitMatrix(input[0].length + 2 * whiteSpace, input.length + 2 * whiteSpace); output.clear(); for (int y = 0, yOutput = output.getHeight() - whiteSpace; y < input.length; y++, yOutput--) { for (int x = 0; x < input[0].length; x++) { // Zero is white in the bytematrix if (input[y][x] == 1) { output.set(x + whiteSpace, yOutput); } } } return output; } /** * Takes and rotates the it 90 degrees */ private static byte[][] rotateArray(byte[][] bitarray) { byte[][] temp = new byte[bitarray[0].length][bitarray.length]; for (int ii = 0; ii < bitarray.length; ii++) { // This makes the direction consistent on screen when rotating the // screen; int inverseii = bitarray.length - ii - 1; for (int jj = 0; jj < bitarray[0].length; jj++) { temp[jj][inverseii] = bitarray[ii][jj]; } } return temp; } }