private DmtxEncode(DmtxEncode src) { this._scheme = src._scheme; this._sizeIdxRequest = src._sizeIdxRequest; this._marginSize = src._marginSize; this._moduleSize = src._moduleSize; this._pixelPacking = src._pixelPacking; this._imageFlip = src._imageFlip; this._rowPadBytes = src._rowPadBytes; this._image = src._image; this._message = src._message; this._method = src._method; this._region = src._region; }
private Bitmap EncodeImage(string val, DmtxImageEncoderOptions options, bool isMosaic) { DmtxEncode encode = new DmtxEncode(); encode.ModuleSize = options.ModuleSize; encode.MarginSize = options.MarginSize; encode.Scheme = options.Scheme; encode.SizeIdxRequest = options.SizeIdx; byte[] valAsByteArray = Encoding.ASCII.GetBytes(val); if (isMosaic) { encode.EncodeDataMosaic(valAsByteArray); } else { encode.EncodeDataMatrix(options.ForeColor, options.BackColor, valAsByteArray); } return CopyDataToBitmap(encode.Image.Pxl, encode.Image.Width, encode.Image.Height); }
internal string EncodeSvgFile(DmtxEncode enc, string format, int moduleSize, int margin, Color foreColor, Color backColor) { int col, row, rowInv; int symbolCols, symbolRows; int width, height, module; bool defineOnly = false; //byte mosaicRed, mosaicGrn, mosaicBlu; string idString = null; string style = ""; string outputString = ""; if (dotFormatProvider == null) { dotFormatProvider = new NumberFormatInfo(); dotFormatProvider.NumberDecimalSeparator = "."; } if (format == "svg:") { defineOnly = true; idString = format.Substring(4); } if (string.IsNullOrEmpty(idString)) { idString = "dmtx_0001"; } width = 2 * enc.MarginSize + (enc.Region.SymbolCols * enc.ModuleSize); height = 2 * enc.MarginSize + (enc.Region.SymbolRows * enc.ModuleSize); symbolCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolCols, enc.Region.SizeIdx); symbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, enc.Region.SizeIdx); /* Print SVG Header */ if (!defineOnly) { outputString += string.Format( "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" + "<!-- Created with DataMatrix.net (http://datamatrixnet.sourceforge.net/) -->\n" + "<svg\n" + "xmlns:svg=\"http://www.w3.org/2000/svg\"\n" + "xmlns=\"http://www.w3.org/2000/svg\"\n" + "xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" + "version=\"1.0\"\n" + "width=\"{0}\"\n" + "height=\"{1}\"\n" + "id=\"svg2\">\n" + "<defs>\n" + "<symbol id=\"{2}\">\n" + " <desc>Layout:{0}x%{1} Symbol:{3}x{4} Data Matrix</desc>\n", width, height, idString, symbolCols, symbolRows); } if (backColor != Color.White) { style = string.Format("style=\"fill:#{0}{1}{2};fill-opacity:{3};stroke:none\" ", backColor.R.ToString("X2"), backColor.G.ToString("X2"), backColor.B.ToString("X2"), ((double)backColor.A / (double)byte.MaxValue).ToString("0.##", dotFormatProvider)); outputString += string.Format(" <rect width=\"{0}\" height=\"{1}\" x=\"0\" y=\"0\" {2}/>\n", width, height, style); style = ""; } /* Write Data Matrix ON modules */ for (row = 0; row < enc.Region.SymbolRows; row++) { rowInv = enc.Region.SymbolRows - row - 1; for (col = 0; col < enc.Region.SymbolCols; col++) { module = enc.Message.SymbolModuleStatus(enc.Region.SizeIdx, row, col); style = string.Format("style=\"fill:#{0}{1}{2};fill-opacity:{3};stroke:none\" ", foreColor.R.ToString("X2"), foreColor.G.ToString("X2"), foreColor.B.ToString("X2"), ((double)foreColor.A / (double)byte.MaxValue).ToString("0.##", dotFormatProvider)); if ((module & DmtxConstants.DmtxModuleOn) != 0) { outputString += string.Format(" <rect width=\"{0}\" height=\"{1}\" x=\"{2}\" y=\"{3}\" {4}/>\n", moduleSize, moduleSize, col * moduleSize + margin, rowInv * moduleSize + margin, style); } } } outputString += " </symbol>\n"; /* Close SVG document */ if (!defineOnly) { outputString += string.Format("</defs>\n" + "<use xlink:href=\"#{0}\" x='0' y='0' style=\"fill:#000000;fill-opacity:1;stroke:none\" />\n" + "\n</svg>\n", idString); } return outputString; }
public string EncodeSvgImage(string val, DmtxImageEncoderOptions options) { DmtxEncode encode = new DmtxEncode(); encode.ModuleSize = options.ModuleSize; encode.MarginSize = options.MarginSize; encode.SizeIdxRequest = options.SizeIdx; encode.Scheme = options.Scheme; byte[] valAsByteArray = Encoding.ASCII.GetBytes(val); encode.EncodeDataMatrix(options.ForeColor, options.BackColor, valAsByteArray); return EncodeSvgFile(encode, "", options.ModuleSize, options.MarginSize, options.ForeColor, options.BackColor); }
internal bool EncodeDataMosaic(byte[] inputString) { int dataWordCount; int tmpInputSize; int inputStartIndex; int[] splitInputSize = new int[3]; DmtxSymbolSize sizeIdx, sizeIdxRequest; DmtxSymbolSize splitSizeIdxAttempt, splitSizeIdxFirst, splitSizeIdxLast; List<byte[]> buf = new List<byte[]>(3); for (int i = 0; i < 3; i++) { buf.Add(new byte[4096]); } DmtxEncode encGreen, encBlue; int row, col, mappingRows, mappingCols; /* 1) count how many codewords it would take to encode the whole thing * 2) take ceiling N of codeword count divided by 3 * 3) using minimum symbol size that can accomodate N codewords: * 4) create several barcodes over iterations of increasing numbers of * input codewords until you go one too far * 5) if codewords remain after filling R, G, and B barcodes then go back * to 3 and try with next larger size * 6) take the 3 different images you created and write out a new barcode */ /* Encode full input string to establish baseline data codeword count */ sizeIdx = sizeIdxRequest = this._sizeIdxRequest; /* XXX buf can be changed here to use all 3 buffers' length */ dataWordCount = EncodeDataCodewords(buf[0], inputString, ref sizeIdx); if (dataWordCount <= 0) return false; /* Use 1/3 (ceiling) of inputSize establish input size target */ tmpInputSize = (inputString.Length + 2) / 3; splitInputSize[0] = tmpInputSize; splitInputSize[1] = tmpInputSize; splitInputSize[2] = inputString.Length - (splitInputSize[0] + splitInputSize[1]); /* XXX clean up above lines later for corner cases */ /* Use 1/3 (floor) of dataWordCount establish first symbol size attempt */ splitSizeIdxFirst = FindCorrectSymbolSize(tmpInputSize, sizeIdxRequest); if (splitSizeIdxFirst == DmtxSymbolSize.DmtxSymbolShapeAuto) return false; /* Set the last possible symbol size for this symbol shape or specific size request */ if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolSquareAuto) { splitSizeIdxLast = DmtxSymbolSize.DmtxSymbol144x144; } else if (sizeIdxRequest == DmtxSymbolSize.DmtxSymbolRectAuto) { splitSizeIdxLast = DmtxSymbolSize.DmtxSymbol16x48; } else { splitSizeIdxLast = splitSizeIdxFirst; } /* XXX would be nice if we could choose a size and then fill up each layer as we go, but this can cause problems with all data fits on first 2 layers. Revisit this later after things look a bit cleaner. */ /* Try increasing symbol sizes until 3 of them can hold all input values */ byte[] tmpRed = new byte[splitInputSize[0]]; for (int i = 0; i < splitInputSize[0]; i++) { tmpRed[i] = inputString[i]; } byte[] tmpGreen = new byte[splitInputSize[1]]; for (int i = splitInputSize[0]; i < splitInputSize[0] + splitInputSize[1]; i++) { tmpGreen[i - splitInputSize[0]] = inputString[i]; } byte[] tmpBlue = new byte[splitInputSize[2]]; for (int i = splitInputSize[0] + splitInputSize[1]; i < inputString.Length; i++) { tmpBlue[i - splitInputSize[0] - splitInputSize[1]] = inputString[i]; } for (splitSizeIdxAttempt = splitSizeIdxFirst; splitSizeIdxAttempt <= splitSizeIdxLast; splitSizeIdxAttempt++) { /* RED LAYER */ sizeIdx = splitSizeIdxAttempt; inputStartIndex = 0; EncodeDataCodewords(buf[0], tmpRed, ref sizeIdx); if (sizeIdx != splitSizeIdxAttempt) continue; /* GREEN LAYER */ sizeIdx = splitSizeIdxAttempt; inputStartIndex += splitInputSize[0]; EncodeDataCodewords(buf[1], tmpGreen, ref sizeIdx); if (sizeIdx != splitSizeIdxAttempt) continue; /* BLUE LAYER */ sizeIdx = splitSizeIdxAttempt; inputStartIndex += splitInputSize[1]; EncodeDataCodewords(buf[2], tmpBlue, ref sizeIdx); if (sizeIdx != splitSizeIdxAttempt) continue; break; } this._sizeIdxRequest = splitSizeIdxAttempt; /* Now we have the correct lengths for splitInputSize, and they all fit into the desired size */ encGreen = new DmtxEncode(this); encBlue = new DmtxEncode(this); /* First encode red to the main encode struct (image portion will be overwritten) */ EncodeDataMatrix(null, null, tmpRed); encGreen.EncodeDataMatrix(null, null, tmpGreen); encBlue.EncodeDataMatrix(null, null, tmpBlue); mappingRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixRows, splitSizeIdxAttempt); mappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, splitSizeIdxAttempt); for (int i = 0; i < this._region.MappingCols * this._region.MappingRows; i++) { this._message.Array[i] = 0; } DmtxDecode.ModulePlacementEcc200(this._message.Array, this._message.Code, this._region.SizeIdx, DmtxConstants.DmtxModuleOnRed); //string s = Encoding.ASCII.GetString(_array); //Console.WriteLine(s); /* Data Mosaic will traverse this array multiple times -- reset DmtxModuleAssigned and DMX_MODULE_VISITED bits before starting */ for (row = 0; row < mappingRows; row++) { for (col = 0; col < mappingCols; col++) { this._message.Array[row * mappingCols + col] &= (byte)(0xff ^ (DmtxConstants.DmtxModuleAssigned | DmtxConstants.DmtxModuleVisited)); } } DmtxDecode.ModulePlacementEcc200(this._message.Array, encGreen.Message.Code, this._region.SizeIdx, DmtxConstants.DmtxModuleOnGreen); /* Data Mosaic will traverse this array multiple times -- reset DmtxModuleAssigned and DMX_MODULE_VISITED bits before starting */ for (row = 0; row < mappingRows; row++) { for (col = 0; col < mappingCols; col++) { this._message.Array[row * mappingCols + col] &= (byte)(0xff ^ (DmtxConstants.DmtxModuleAssigned | DmtxConstants.DmtxModuleVisited)); } } DmtxDecode.ModulePlacementEcc200(this._message.Array, encBlue.Message.Code, this._region.SizeIdx, DmtxConstants.DmtxModuleOnBlue); PrintPattern(null, null); return true; }