/* * Copyright 2013 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. */ using System; using System.Collections.Generic; using System.Text; using ZXing.Aztec.Internal; using ZXing.Common; namespace ZXing.Aztec { /// /// Generates Aztec 2D barcodes. /// public sealed class AztecWriter : Writer { private static readonly Encoding DEFAULT_CHARSET; static AztecWriter() { #if !(WindowsCE || SILVERLIGHT4 || SILVERLIGHT5 || NETFX_CORE || PORTABLE) DEFAULT_CHARSET = Encoding.GetEncoding("ISO-8859-1"); #elif WindowsCE try { DEFAULT_CHARSET = Encoding.GetEncoding("ISO-8859-1"); } catch (PlatformNotSupportedException) { DEFAULT_CHARSET = Encoding.GetEncoding(1252); } #else // not fully correct but what else DEFAULT_CHARSET = Encoding.GetEncoding("UTF-8"); #endif } /// /// Encode a barcode using the default settings. /// /// The contents to encode in the barcode /// The barcode format to generate /// The preferred width in pixels /// The preferred height in pixels /// /// The generated barcode as a Matrix of unsigned bytes (0 == black, 255 == white) /// public BitMatrix encode(String contents, BarcodeFormat format, int width, int height) { return encode(contents, format, width, height, null); } /// /// /// The contents to encode in the barcode /// The barcode format to generate /// The preferred width in pixels /// The preferred height in pixels /// Additional parameters to supply to the encoder /// /// The generated barcode as a Matrix of unsigned bytes (0 == black, 255 == white) /// public BitMatrix encode(String contents, BarcodeFormat format, int width, int height, IDictionary hints) { var charset = DEFAULT_CHARSET; int eccPercent = Internal.Encoder.DEFAULT_EC_PERCENT; int layers = Internal.Encoder.DEFAULT_AZTEC_LAYERS; if (hints != null) { if (hints.ContainsKey(EncodeHintType.CHARACTER_SET)) { object charsetname = hints[EncodeHintType.CHARACTER_SET]; if (charsetname != null) { charset = Encoding.GetEncoding(charsetname.ToString()); } } if (hints.ContainsKey(EncodeHintType.ERROR_CORRECTION)) { object eccPercentObject = hints[EncodeHintType.ERROR_CORRECTION]; if (eccPercentObject != null) { eccPercent = Convert.ToInt32(eccPercentObject); } } if (hints.ContainsKey(EncodeHintType.AZTEC_LAYERS)) { object layersObject = hints[EncodeHintType.AZTEC_LAYERS]; if (layersObject != null) { layers = Convert.ToInt32(layersObject); } } } return encode(contents, format, width, height, charset, eccPercent, layers); } private static BitMatrix encode(String contents, BarcodeFormat format, int width, int height, Encoding charset, int eccPercent, int layers) { if (format != BarcodeFormat.AZTEC) { throw new ArgumentException("Can only encode AZTEC code, but got " + format); } var aztec = Internal.Encoder.encode(charset.GetBytes(contents), eccPercent, layers); return renderResult(aztec, width, height); } private static BitMatrix renderResult(AztecCode code, int width, int height) { var input = code.Matrix; if (input == null) { throw new InvalidOperationException("No input code matrix"); } int inputWidth = input.Width; int inputHeight = input.Height; int outputWidth = Math.Max(width, inputWidth); int outputHeight = Math.Max(height, inputHeight); int multiple = Math.Min(outputWidth / inputWidth, outputHeight / inputHeight); int leftPadding = (outputWidth - (inputWidth * multiple)) / 2; int topPadding = (outputHeight - (inputHeight * multiple)) / 2; var output = new BitMatrix(outputWidth, outputHeight); for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) { // Write the contents of this row of the barcode for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) { if (input[inputX, inputY]) { output.setRegion(outputX, outputY, multiple, multiple); } } } return output; } } }