/// <summary> /// Renders the matrix in an Encapsuled PostScript format. /// </summary> /// <param name="matrix">The matrix to be rendered</param> /// <param name="stream">Output stream that must be writable</param> /// <remarks></remarks> public void WriteToStream(BitMatrix matrix, Stream stream) { using (var writer = new StreamWriter(stream)) { int width = matrix == null ? 21 : matrix.Width; DrawingSize drawingSize = m_iSize.GetSize(width); OutputHeader(drawingSize, writer); OutputBackground(writer); if (matrix != null) { switch (m_DrawingTechnique) { case EpsModuleDrawingTechnique.Squares: DrawSquares(matrix, writer); break; case EpsModuleDrawingTechnique.Image: DrawImage(matrix, writer); break; default: throw new ArgumentOutOfRangeException("DrawingTechnique"); } } OutputFooter(writer); } }
/// <summary> /// Outputs the EPS header with mandatory declarations, variable declarations and function definitions. /// </summary> /// <param name="drawingSize">Size of the drawing.</param> /// <param name="stream">Output text stream</param> /// <remarks></remarks> private void OutputHeader(DrawingSize drawingSize, StreamWriter stream) { string strHeader = @"%!PS-Adobe-3.0 EPSF-3.0 %%Creator: Gma.QrCodeNet %%Title: QR Code %%CreationDate: {0:yyyyMMdd} %%Pages: 1 %%BoundingBox: 0 0 {1} {2} %%Document-Fonts: Times-Roman %%LanguageLevel: 1 %%EndComments %%BeginProlog /w {{ {3} }} def /h {{ {4} }} def /q {{ {5} }} def /s {{ {6} }} def /W {{ w q q add add }} def /H {{ h q q add add }} def"; string strBoxFunctions = @"% Define the box functions taking X and Y coordinates of the top left corner and filling a 1 point large square /b { newpath moveto 1 0 rlineto 0 1 rlineto -1 0 rlineto closepath fill } def /br { newpath moveto 1.01 0 rlineto 0 1 rlineto -1.01 0 rlineto closepath fill } def /bb { newpath moveto 1 0 rlineto 0 1.01 rlineto -1 0 rlineto closepath fill } def /brb { newpath moveto 1.01 0 rlineto 0 1 rlineto -0.01 0 rlineto 0 0.01 rlineto -1 0 rlineto closepath fill } def"; string strHeaderEnd = @"%%EndProlog %%Page: 1 1 % Save the current state save % Invert the Y axis 0 W s mul translate s s neg scale"; stream.WriteLine(string.Format(strHeader, DateTime.UtcNow, // Use invariant culture to ensure that the dot is used as the decimal separator (drawingSize.CodeWidth).ToString(CultureInfo.InvariantCulture.NumberFormat), // Size in points of the matrix with the quiet zone (drawingSize.CodeWidth).ToString(CultureInfo.InvariantCulture.NumberFormat), drawingSize.CodeWidth / drawingSize.ModuleSize - ((int)drawingSize.QuietZoneModules * 2), // Number of modules of the matrix without the quiet zone drawingSize.CodeWidth / drawingSize.ModuleSize - ((int)drawingSize.QuietZoneModules * 2), (int)drawingSize.QuietZoneModules, // Number of quiet zone modules drawingSize.ModuleSize.ToString(CultureInfo.InvariantCulture.NumberFormat))); // Size in points of a single module if (m_DrawingTechnique == EpsModuleDrawingTechnique.Squares) { stream.WriteLine(strBoxFunctions); } stream.WriteLine(strHeaderEnd); }
/// <summary> /// Writes to bitmap source. /// </summary> /// <param name="QrMatrix">The qr matrix.</param> /// <param name="DPI">The DPI.</param> /// <returns></returns> /// <remarks></remarks> public BitmapSource WriteToBitmapSource(BitMatrix QrMatrix, Point DPI) { int width = QrMatrix == null ? 21 : QrMatrix.Width; DrawingSize dSize = m_ISize.GetSize(width); var quietZone = (int)dSize.QuietZoneModules; GeometryDrawing quietZoneDrawing = ConstructQZDrawing(2 * quietZone + width); GeometryDrawing qrDrawing = ConstructQrDrawing(QrMatrix, quietZone, quietZone); var qrGroup = new DrawingGroup(); qrGroup.Children.Add(quietZoneDrawing); qrGroup.Children.Add(qrDrawing); DrawingBrush qrBrush = ConstructDrawingBrush(qrGroup); PixelFormat pixelFormat = PixelFormats.Pbgra32; var renderbmp = new RenderTargetBitmap(dSize.CodeWidth, dSize.CodeWidth, DPI.X, DPI.Y, pixelFormat); var drawingVisual = new DrawingVisual(); using (DrawingContext dContext = drawingVisual.RenderOpen()) { dContext.DrawRectangle(qrBrush, null, new Rect(0, 0, (dSize.CodeWidth / DPI.X) * 96, (dSize.CodeWidth / DPI.Y) * 96)); } renderbmp.Render(drawingVisual); return(renderbmp); }
/// <summary> /// Saves QrCode Image to specified stream in the specified format /// </summary> /// <param name="QrMatrix">The qr matrix.</param> /// <param name="imageFormat">The image format.</param> /// <param name="stream">The stream.</param> /// <param name="DPI">The DPI.</param> /// <exception cref="ArgumentNullException">Stream or Format is null</exception> /// /// <exception cref="ExternalException">The image was saved with the wrong image format</exception> /// <remarks>You should avoid saving an image to the same stream that was used to construct. Doing so might damage the stream /// If any additional data has been written to the stream before saving the image, the image data in the stream will be corrupted</remarks> public void WriteToStream(BitMatrix QrMatrix, ImageFormat imageFormat, Stream stream, Point DPI) { if (imageFormat == ImageFormat.Emf || imageFormat == ImageFormat.Wmf) { CreateMetaFile(QrMatrix, stream); } else if (imageFormat != ImageFormat.Exif && imageFormat != ImageFormat.Icon && imageFormat != ImageFormat.MemoryBmp) { DrawingSize size = m_iSize.GetSize(QrMatrix == null ? 21 : QrMatrix.Width); using (var bitmap = new Bitmap(size.CodeWidth, size.CodeWidth)) { if (DPI.X != 96 || DPI.Y != 96) { bitmap.SetResolution(DPI.X, DPI.Y); } using (Graphics graphics = Graphics.FromImage(bitmap)) { Draw(graphics, QrMatrix); bitmap.Save(stream, imageFormat); } } } }
/// <summary> /// Drawing Bitmatrix to winform graphics. /// </summary> /// <param name="graphics">The graphics.</param> /// <param name="QrMatrix">Draw background only for null matrix</param> /// <param name="offset">The offset.</param> /// <exception cref="ArgumentNullException">DarkBrush or LightBrush is null</exception> /// <remarks></remarks> public void Draw(Graphics graphics, BitMatrix QrMatrix, Point offset) { int width = QrMatrix == null ? 21 : QrMatrix.Width; DrawingSize size = m_iSize.GetSize(width); graphics.FillRectangle(m_LightBrush, offset.X, offset.Y, size.CodeWidth, size.CodeWidth); if (QrMatrix == null || size.ModuleSize == 0) { return; } int padding = (size.CodeWidth - (size.ModuleSize * width)) / 2; int preX = -1; for (int y = 0; y < width; y++) { for (int x = 0; x < width; x++) { if (QrMatrix[x, y]) { //Set start point if preX == -1 if (preX == -1) { preX = x; } //If this is last module in that row. Draw rectangle if (x == width - 1) { var modulePosition = new Point(preX * size.ModuleSize + padding + offset.X, y * size.ModuleSize + padding + offset.Y); var rectSize = new Size((x - preX + 1) * size.ModuleSize, size.ModuleSize); graphics.FillRectangle(m_DarkBrush, modulePosition.X, modulePosition.Y, rectSize.Width, rectSize.Height); preX = -1; } } else if (!QrMatrix[x, y] && preX != -1) { //Here will be first light module after sequence of dark module. //Draw previews sequence of dark Module var modulePosition = new Point(preX * size.ModuleSize + padding + offset.X, y * size.ModuleSize + padding + offset.Y); var rectSize = new Size((x - preX) * size.ModuleSize, size.ModuleSize); graphics.FillRectangle(m_DarkBrush, modulePosition.X, modulePosition.Y, rectSize.Width, rectSize.Height); preX = -1; } } } }
/// <summary> /// Writes to stream. /// </summary> /// <param name="qrMatrix">The qr matrix.</param> /// <param name="imageFormat">The image format.</param> /// <param name="stream">The stream.</param> /// <remarks></remarks> public void WriteToStream(BitMatrix qrMatrix, ImageFormatEnum imageFormat, Stream stream) { DrawingSize dSize = ISize.GetSize(qrMatrix == null ? 21 : qrMatrix.Width); var wBitmap = new WriteableBitmap(dSize.CodeWidth, dSize.CodeWidth, 96, 96, PixelFormats.Gray8, null); Draw(wBitmap, qrMatrix); BitmapEncoder encoder = imageFormat.ChooseEncoder(); encoder.Frames.Add(BitmapFrame.Create(wBitmap)); encoder.Save(stream); }
/// <summary> /// Draw QrCode at given writeable bitmap at offset location /// </summary> /// <param name="wBitmap">The w bitmap.</param> /// <param name="matrix">The matrix.</param> /// <param name="offsetX">The offset X.</param> /// <param name="offsetY">The offset Y.</param> /// <remarks></remarks> public void Draw(WriteableBitmap wBitmap, BitMatrix matrix, int offsetX, int offsetY) { DrawingSize size = matrix == null?ISize.GetSize(21) : ISize.GetSize(matrix.Width); if (wBitmap == null) { wBitmap = new WriteableBitmap(size.CodeWidth + offsetX, size.CodeWidth + offsetY, 96, 96, PixelFormats.Gray8, null); } else if (wBitmap.PixelHeight == 0 || wBitmap.PixelWidth == 0) { return; //writeablebitmap contains no pixel. } DrawQuietZone(wBitmap, size.CodeWidth, offsetX, offsetY); if (matrix == null) { return; } DrawDarkModule(wBitmap, matrix, offsetX, offsetY); }
/// <summary> /// Draw qrCode dark modules at given position. (It will also include quiet zone area. Set it to zero to exclude quiet zone) /// </summary> /// <param name="wBitmap">The w bitmap.</param> /// <param name="matrix">The matrix.</param> /// <param name="offsetX">The offset X.</param> /// <param name="offsetY">The offset Y.</param> /// <exception cref="ArgumentNullException">Bitmatrix, wBitmap should not equal to null</exception> /// /// <exception cref="ArgumentOutOfRangeException">wBitmap's pixel width or height should not equal to zero</exception> /// <remarks></remarks> public void DrawDarkModule(WriteableBitmap wBitmap, BitMatrix matrix, int offsetX, int offsetY) { if (matrix == null) { throw new ArgumentNullException("Bitmatrix"); } DrawingSize size = ISize.GetSize(matrix.Width); if (wBitmap == null) { throw new ArgumentNullException("wBitmap"); } else if (wBitmap.PixelHeight == 0 || wBitmap.PixelWidth == 0) { throw new ArgumentOutOfRangeException("wBitmap", "WriteableBitmap's pixelHeight or PixelWidth are equal to zero"); } int padding = (size.CodeWidth - size.ModuleSize * matrix.Width) / 2; int preX = -1; int moduleSize = size.ModuleSize; if (moduleSize == 0) { return; } for (int y = 0; y < matrix.Width; y++) { for (int x = 0; x < matrix.Width; x++) { if (matrix[x, y]) { if (preX == -1) { preX = x; } if (x == matrix.Width - 1) { var moduleArea = new Int32Rect(preX * moduleSize + padding + offsetX, y * moduleSize + padding + offsetY, (x - preX + 1) * moduleSize, moduleSize); wBitmap.FillRectangle(moduleArea, DarkColor); preX = -1; } } else if (preX != -1) { var moduleArea = new Int32Rect(preX * moduleSize + padding + offsetX, y * moduleSize + padding + offsetY, (x - preX) * moduleSize, moduleSize); wBitmap.FillRectangle(moduleArea, DarkColor); preX = -1; } } } }