public override BitMatrix sampleGrid(BitMatrix image, int dimensionX, int dimensionY, float p1ToX, float p1ToY, float p2ToX, float p2ToY, float p3ToX, float p3ToY, float p4ToX, float p4ToY, float p1FromX, float p1FromY, float p2FromX, float p2FromY, float p3FromX, float p3FromY, float p4FromX, float p4FromY)
 {
    PerspectiveTransform transform = PerspectiveTransform.quadrilateralToQuadrilateral(
       p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY, 
       p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
    return sampleGrid(image, dimensionX, dimensionY, transform);
 }
	/// <summary>
	/// Encode the specified string .
	/// </summary>
	/// <param name="valueStr"> content string.</param>
	public void Encode(string valueStr)
	{
	//	var writer = new QRCodeWriter();
		var writer = new MultiFormatWriter();
		Dictionary<EncodeHintType, object> hints = new Dictionary<EncodeHintType, object>();  
		//set the code type
		hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");  

		byteMatrix = writer.encode( valueStr, BarcodeFormat.QR_CODE, e_QRCodeWidth, e_QRCodeHeight,hints); 
		//writer1.encode("ddd",BarcodeFormat.
		for (int i =0; i!= e_QRCodeWidth; i++) {
			for(int j = 0;j!= e_QRCodeHeight;j++)
			{
				if(byteMatrix[i,j])
				{
					m_EncodedTex.SetPixel(i,j,Color.black);
				}
				else
				{
					m_EncodedTex.SetPixel(i,j,Color.white);
				}
			}
		}

		///rotation the image 
		Color32[] pixels = m_EncodedTex.GetPixels32();
		pixels = RotateMatrixByClockwise(pixels, m_EncodedTex.width);
		m_EncodedTex.SetPixels32(pixels); 

		m_EncodedTex.Apply ();

		e_QREncodeFinished (m_EncodedTex);
	}
Example #3
0
      public override Bitmap Render(BitMatrix matrix, BarcodeFormat format, string content, EncodingOptions options)
      {
         int width = matrix.Width;
         int height = matrix.Height;

         var backgroundBrush = new LinearGradientBrush(
            new Rectangle(0, 0, width, height), BackgroundGradientColor, Background, LinearGradientMode.Vertical);
         var foregroundBrush = new LinearGradientBrush(
            new Rectangle(0, 0, width, height), ForegroundGradientColor, Foreground, LinearGradientMode.ForwardDiagonal);

         var bmp = new Bitmap(width, height);
         var gg = Graphics.FromImage(bmp);
         gg.Clear(Background);

         for (int x = 0; x < width - 1; x++)
         {
            for (int y = 0; y < height - 1; y++)
            {
               if (matrix[x, y])
               {
                  gg.FillRectangle(foregroundBrush, x, y, 1, 1);
               }
               else
               {
                  gg.FillRectangle(backgroundBrush, x, y, 1, 1);
               }
            }
         }

         return bmp;
      }
Example #4
0
 internal BinaryBitmap(BitMatrix matrix)
 {
    if (matrix == null)
    {
       throw new ArgumentException("matrix must be non-null.");
    }
    this.matrix = matrix;
 }
      public override BitMatrix sampleGrid(BitMatrix image, int dimensionX, int dimensionY, PerspectiveTransform transform)
      {
         if (dimensionX <= 0 || dimensionY <= 0)
         {
            return null;
         }
         BitMatrix bits = new BitMatrix(dimensionX, dimensionY);
         float[] points = new float[dimensionX << 1];
         for (int y = 0; y < dimensionY; y++)
         {
            int max = points.Length;
            //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
            float iValue = (float)y + 0.5f;
            for (int x = 0; x < max; x += 2)
            {
               //UPGRADE_WARNING: Data types in Visual C# might be different.  Verify the accuracy of narrowing conversions. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1042'"
               points[x] = (float)(x >> 1) + 0.5f;
               points[x + 1] = iValue;
            }
            transform.transformPoints(points);
            // Quick check to see if points transformed to something inside the image;
            // sufficient to check the endpoints
            if (!checkAndNudgePoints(image, points))
               return null;
            try
            {
               var imageWidth = image.Width;
               var imageHeight = image.Height;

               for (int x = 0; x < max; x += 2)
               {
                  var imagex = (int)points[x];
                  var imagey = (int)points[x + 1];

                  if (imagex < 0 || imagex >= imageWidth || imagey < 0 || imagey >= imageHeight)
                  {
                     return null;
                  }

                  bits[x >> 1, y] = image[imagex, imagey];
               }
            }
            catch (System.IndexOutOfRangeException)
            {
               // java version:
               // 
               // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
               // transform gets "twisted" such that it maps a straight line of points to a set of points
               // whose endpoints are in bounds, but others are not. There is probably some mathematical
               // way to detect this about the transformation that I don't know yet.
               // This results in an ugly runtime exception despite our clever checks above -- can't have
               // that. We could check each point's coordinates but that feels duplicative. We settle for
               // catching and wrapping ArrayIndexOutOfBoundsException.
               return null;
            }
         }
         return bits;
      }
 /// <param name="bitMatrix">{@link BitMatrix} to parse</param>
 /// <throws>ReaderException if dimension is not >= 21 and 1 mod 4</throws>
 internal static BitMatrixParser createBitMatrixParser(BitMatrix bitMatrix)
 {
    int dimension = bitMatrix.Height;
    if (dimension < 21 || (dimension & 0x03) != 1)
    {
       return null;
    }
    return new BitMatrixParser(bitMatrix);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="AztecDetectorResult"/> class.
 /// </summary>
 /// <param name="bits">The bits.</param>
 /// <param name="points">The points.</param>
 /// <param name="compact">if set to <c>true</c> [compact].</param>
 /// <param name="nbDatablocks">The nb datablocks.</param>
 /// <param name="nbLayers">The nb layers.</param>
 public AztecDetectorResult(BitMatrix bits,
                            ResultPoint[] points,
                            bool compact,
                            int nbDatablocks,
                            int nbLayers)
    : base(bits, points)
 {
    Compact = compact;
    NbDatablocks = nbDatablocks;
    NbLayers = nbLayers;
 }
Example #8
0
      /// <summary> <p>Implementations of this method reverse the data masking process applied to a QR Code and
      /// make its bits ready to read.</p>
      /// </summary>
      /// <param name="reference"></param>
      /// <param name="bits">representation of QR Code bits</param>
      /// <param name="dimension">dimension of QR Code, represented by bits, being unmasked</param>
      internal static void unmaskBitMatrix(int reference, BitMatrix bits, int dimension)
      {
         if (reference < 0 || reference > 7)
         {
            throw new System.ArgumentException();
         }

         var isMasked = DATA_MASKS[reference];

         bits.flipWhen(isMasked);
      }
 /// <summary> <p>Creates a finder that will look in a portion of the whole image.</p>
 /// 
 /// </summary>
 /// <param name="image">image to search
 /// </param>
 /// <param name="startX">left column from which to start searching
 /// </param>
 /// <param name="startY">top row from which to start searching
 /// </param>
 /// <param name="width">width of region to search
 /// </param>
 /// <param name="height">height of region to search
 /// </param>
 /// <param name="moduleSize">estimated module size so far
 /// </param>
 internal AlignmentPatternFinder(BitMatrix image, int startX, int startY, int width, int height, float moduleSize, ResultPointCallback resultPointCallback)
 {
    this.image = image;
    this.possibleCenters = new List<AlignmentPattern>(5);
    this.startX = startX;
    this.startY = startY;
    this.width = width;
    this.height = height;
    this.moduleSize = moduleSize;
    this.crossCheckStateCount = new int[3];
    this.resultPointCallback = resultPointCallback;
 }
Example #10
0
 /// <summary>
 ///   <p>Convenience method that can decode a QR Code represented as a 2D array of booleans.
 /// "true" is taken to mean a black module.</p>
 /// </summary>
 /// <param name="image">booleans representing white/black QR Code modules</param>
 /// <param name="hints">The hints.</param>
 /// <returns>
 /// text and bytes encoded within the QR Code
 /// </returns>
 public DecoderResult decode(bool[][] image, IDictionary<DecodeHintType, object> hints)
 {
    int dimension = image.Length;
    BitMatrix bits = new BitMatrix(dimension);
    for (int i = 0; i < dimension; i++)
    {
       for (int j = 0; j < dimension; j++)
       {
          bits[j, i] = image[i][j];
       }
    }
    return decode(bits, hints);
 }
Example #11
0
 /// <summary> <p>Implementations of this method reverse the data masking process applied to a QR Code and
 /// make its bits ready to read.</p>
 /// 
 /// </summary>
 /// <param name="bits">representation of QR Code bits
 /// </param>
 /// <param name="dimension">dimension of QR Code, represented by bits, being unmasked
 /// </param>
 internal void unmaskBitMatrix(BitMatrix bits, int dimension)
 {
    for (int i = 0; i < dimension; i++)
    {
       for (int j = 0; j < dimension; j++)
       {
          if (isMasked(i, j))
          {
             bits.flip(j, i);
          }
       }
    }
 }
Example #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ZXing.PDF417.Internal.BoundingBox"/> class.
 /// Will throw an exception if the corner points don't match up correctly
 /// </summary>
 /// <param name="image">Image.</param>
 /// <param name="topLeft">Top left.</param>
 /// <param name="topRight">Top right.</param>
 /// <param name="bottomLeft">Bottom left.</param>
 /// <param name="bottomRight">Bottom right.</param>
 private BoundingBox(BitMatrix image,
                     ResultPoint topLeft,
                     ResultPoint bottomLeft,
                     ResultPoint topRight,
                     ResultPoint bottomRight)
 {
    this.image = image;
    this.TopLeft = topLeft;
    this.TopRight = topRight;
    this.BottomLeft = bottomLeft;
    this.BottomRight = bottomRight;
    calculateMinMaxValues();
 }
        /// <summary>
        /// برسی وجود کد QR در تصویر
        /// </summary>
        /// <param name="bitmapByteArray">تصویر مورد نظر در قالب آرایه ای از <c>byte</c></param>
        /// <param name="width">عرض تصویر به پیکسل</param>
        /// <param name="height">طور تصویر به پیکسل</param>
        /// <returns>نتیجه برسی</returns>
        public bool ContainsQRCode(byte[] bitmapByteArray, int width, int height)
        {
            ///[Checking picture for QR Code]
            ZXing.LuminanceSource        source    = new ZXing.RGBLuminanceSource(bitmapByteArray, width, height);
            ZXing.Common.HybridBinarizer binarizer = new ZXing.Common.HybridBinarizer(source);
            ZXing.BinaryBitmap           binBitmap = new ZXing.BinaryBitmap(binarizer);
            ZXing.Common.BitMatrix       bitMatrix = binBitmap.BlackMatrix;

            ZXing.Multi.QrCode.Internal.MultiDetector detector = new ZXing.Multi.QrCode.Internal.MultiDetector(bitMatrix);

            return(detector.detect() != null);
            ///[Checking picture for QR Code]
        }
      /// <summary>
      /// <param name="bitMatrix"><see cref="BitMatrix" />to parse</param>
      /// <exception cref="FormatException">if dimension is < 8 or >144 or not 0 mod 2</exception>
      /// </summary>
      internal BitMatrixParser(BitMatrix bitMatrix)
      {
         int dimension = bitMatrix.Height;
         if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0)
         {
            return;
         }

         version = readVersion(bitMatrix);
         if (version != null)
         {
            mappingBitMatrix = extractDataRegion(bitMatrix);
            readMappingMatrix = new BitMatrix(mappingBitMatrix.Width, mappingBitMatrix.Height);
         }
      }
Example #15
0
 /// <summary>
 /// <p>Convenience method that can decode a Data Matrix Code represented as a 2D array of booleans.
 /// "true" is taken to mean a black module.</p>
 ///
 /// <param name="image">booleans representing white/black Data Matrix Code modules</param>
 /// <returns>text and bytes encoded within the Data Matrix Code</returns>
 /// <exception cref="FormatException">if the Data Matrix Code cannot be decoded</exception>
 /// <exception cref="ChecksumException">if error correction fails</exception>
 /// </summary>
 public DecoderResult decode(bool[][] image)
 {
    int dimension = image.Length;
    BitMatrix bits = new BitMatrix(dimension);
    for (int i = 0; i < dimension; i++)
    {
       for (int j = 0; j < dimension; j++)
       {
          if (image[i][j])
          {
             bits[j, i] = true;
          }
       }
    }
    return decode(bits);
 }
Example #16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ZXing.PDF417.Internal.BoundingBox"/> class.
        /// returns null if the corner points don't match up correctly
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="topLeft">The top left.</param>
        /// <param name="bottomLeft">The bottom left.</param>
        /// <param name="topRight">The top right.</param>
        /// <param name="bottomRight">The bottom right.</param>
        /// <returns></returns>
        public static BoundingBox Create(BitMatrix image,
                                         ResultPoint topLeft,
                                         ResultPoint bottomLeft,
                                         ResultPoint topRight,
                                         ResultPoint bottomRight)
        {
            if ((topLeft == null && topRight == null) ||
                (bottomLeft == null && bottomRight == null) ||
                (topLeft != null && bottomLeft == null) ||
                (topRight != null && bottomRight == null))
            {
                return null;
            }

            return new BoundingBox(image, topLeft, bottomLeft, topRight, bottomRight);
        }
Example #17
0
        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="msg">二维码信息</param>
        /// <returns>图片</returns>
        private Bitmap GenByZXingNet(string msg)
        {
            BarcodeWriter writer = new BarcodeWriter();

            writer.Format = BarcodeFormat.QR_CODE;
            writer.Options.Hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8"); //编码问题
            writer.Options.Hints.Add(EncodeHintType.ERROR_CORRECTION, ZXing.QrCode.Internal.ErrorCorrectionLevel.H);
            const int codeSizeInPixels = 150;                                //设置图片长宽

            writer.Options.Height = writer.Options.Width = codeSizeInPixels;
            writer.Options.Margin = 0;//设置边框
            ZXing.Common.BitMatrix bm = writer.Encode(msg);
            Bitmap img = writer.Write(bm);

            //pictureBox1.Image = img;
            return(img);
        }
Example #18
0
      /// <summary>
      ///   <p>Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module.</p>
      /// </summary>
      /// <param name="bits">booleans representing white/black QR Code modules</param>
      /// <param name="hints">The hints.</param>
      /// <returns>
      /// text and bytes encoded within the QR Code
      /// </returns>
      public DecoderResult decode(BitMatrix bits, IDictionary<DecodeHintType, object> hints)
      {
         // Construct a parser and read version, error-correction level
         var parser = BitMatrixParser.createBitMatrixParser(bits);
         if (parser == null)
            return null;

         var result = decode(parser, hints);
         if (result == null)
         {
            // Revert the bit matrix
            parser.remask();

            // Will be attempting a mirrored reading of the version and format info.
            parser.setMirror(true);

            // Preemptively read the version.
            var version = parser.readVersion();
            if (version == null)
               return null;

            // Preemptively read the format information.
            var formatinfo = parser.readFormatInformation();
            if (formatinfo == null)
               return null;

            /*
             * Since we're here, this means we have successfully detected some kind
             * of version and format information when mirrored. This is a good sign,
             * that the QR code may be mirrored, and we should try once more with a
             * mirrored content.
             */
            // Prepare for a mirrored reading.
            parser.mirror();

            result = decode(parser, hints);

            if (result != null)
            {
               // Success! Notify the caller that the code was mirrored.
               result.Other = new QRCodeDecoderMetaData(true);
            }
         }

         return result;
      }
Example #19
0
      /// <summary>
      ///   <p>Decodes a QR Code represented as a {@link BitMatrix}. A 1 or "true" is taken to mean a black module.</p>
      /// </summary>
      /// <param name="bits">booleans representing white/black QR Code modules</param>
      /// <param name="hints">The hints.</param>
      /// <returns>
      /// text and bytes encoded within the QR Code
      /// </returns>
      public DecoderResult decode(BitMatrix bits, IDictionary<DecodeHintType, object> hints)
      {
         // Construct a parser and read version, error-correction level
         BitMatrixParser parser = BitMatrixParser.createBitMatrixParser(bits);
         if (parser == null)
            return null;
         Version version = parser.readVersion();
         if (version == null)
            return null;
         var formatinfo = parser.readFormatInformation();
         if (formatinfo == null)
            return null;
         ErrorCorrectionLevel ecLevel = formatinfo.ErrorCorrectionLevel;

         // Read codewords
         byte[] codewords = parser.readCodewords();
         if (codewords == null)
            return null;
         // Separate into data blocks
         DataBlock[] dataBlocks = DataBlock.getDataBlocks(codewords, version, ecLevel);

         // Count total number of data bytes
         int totalBytes = 0;
         foreach (var dataBlock in dataBlocks)
         {
            totalBytes += dataBlock.NumDataCodewords;
         }
         byte[] resultBytes = new byte[totalBytes];
         int resultOffset = 0;

         // Error-correct and copy data blocks together into a stream of bytes
         foreach (var dataBlock in dataBlocks)
         {
            byte[] codewordBytes = dataBlock.Codewords;
            int numDataCodewords = dataBlock.NumDataCodewords;
            if (!correctErrors(codewordBytes, numDataCodewords))
               return null;
            for (int i = 0; i < numDataCodewords; i++)
            {
               resultBytes[resultOffset++] = codewordBytes[i];
            }
         }

         // Decode the contents of that stream of bytes
         return DecodedBitStreamParser.decode(resultBytes, version, ecLevel, hints);
      }
Example #20
0
        public static Bitmap Createwm(string asset, int x, int y)
        {
            Bitmap result = null;

            try {
                BarcodeWriter barCodeWriter = new BarcodeWriter();
                barCodeWriter.Format = BarcodeFormat.QR_CODE;
                barCodeWriter.Options.Hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
                barCodeWriter.Options.Hints.Add(EncodeHintType.ERROR_CORRECTION, ZXing.QrCode.Internal.ErrorCorrectionLevel.H);
                barCodeWriter.Options.Height = y;
                barCodeWriter.Options.Width  = x;
                barCodeWriter.Options.Margin = 0;
                ZXing.Common.BitMatrix bm = barCodeWriter.Encode(asset);
                result = barCodeWriter.Write(bm);
                return(result);
            } catch {
                return(null);
            }
        }
        private static int CalcBlackLineWidth(ZXing.Common.BitMatrix bitMatrix, Point[] scanLine)
        {
            int blackLineWidth = 0;
            int i = scanLine[1].X;
            int j = scanLine[1].Y;

            Point scanLineVector = GetScanLineVector(scanLine);

            // черную посчитаем
            for (; i >= 0 && i < bitMatrix.Width && j >= 0 && j < bitMatrix.Height; i += scanLineVector.X, j += scanLineVector.Y)
            {
                if (bitMatrix[i, j] == false)
                {
                    break;
                }
                blackLineWidth++;
            }
            return(blackLineWidth);
        }
Example #22
0
      /// <summary>
      /// <p>Decodes a Data Matrix Code represented as a <see cref="BitMatrix" />. A 1 or "true" is taken
      /// to mean a black module.</p>
      /// </summary>
      /// <param name="bits">booleans representing white/black Data Matrix Code modules</param>
      /// <returns>text and bytes encoded within the Data Matrix Code</returns>
      public DecoderResult decode(BitMatrix bits)
      {
         // Construct a parser and read version, error-correction level
         BitMatrixParser parser = new BitMatrixParser(bits);
         if (parser.Version == null)
            return null;

         // Read codewords
         byte[] codewords = parser.readCodewords();
         if (codewords == null)
            return null;
         // Separate into data blocks
         DataBlock[] dataBlocks = DataBlock.getDataBlocks(codewords, parser.Version);

         int dataBlocksCount = dataBlocks.Length;

         // Count total number of data bytes
         int totalBytes = 0;
         foreach (var db in dataBlocks)
         {
            totalBytes += db.NumDataCodewords;
         }
         byte[] resultBytes = new byte[totalBytes];

         // Error-correct and copy data blocks together into a stream of bytes
         for (int j = 0; j < dataBlocksCount; j++)
         {
            DataBlock dataBlock = dataBlocks[j];
            byte[] codewordBytes = dataBlock.Codewords;
            int numDataCodewords = dataBlock.NumDataCodewords;
            if (!correctErrors(codewordBytes, numDataCodewords))
               return null;
            for (int i = 0; i < numDataCodewords; i++)
            {
               // De-interlace data blocks.
               resultBytes[i * dataBlocksCount + j] = codewordBytes[i];
            }
         }

         // Decode the contents of that stream of bytes
         return DecodedBitStreamParser.decode(resultBytes);
      }
Example #23
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ZXing.PDF417.Internal.BoundingBox"/> class.
        /// Will throw an exception if the corner points don't match up correctly
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="topLeft">Top left.</param>
        /// <param name="topRight">Top right.</param>
        /// <param name="bottomLeft">Bottom left.</param>
        /// <param name="bottomRight">Bottom right.</param>
        public BoundingBox(BitMatrix image, 
                           ResultPoint topLeft, 
                           ResultPoint bottomLeft,
                           ResultPoint topRight, 
                           ResultPoint bottomRight)
        {
            if ((topLeft == null && topRight == null) ||
                (bottomLeft == null && bottomRight == null) ||
                (topLeft != null && bottomLeft == null) ||
                (topRight != null && bottomRight == null))
            {
                throw ReaderException.Instance;
            }

            this.Image = image;
            this.TopLeft = topLeft;
            this.TopRight = topRight;
            this.BottomLeft = bottomLeft;
            this.BottomRight = bottomRight;
            CalculateMinMaxValues();
        }
Example #24
0
        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="strMessage">二维码信息</param>
        /// <param name="width">宽</param>
        /// <param name="height">高</param>
        /// <returns></returns>
        public static Bitmap GetQRCodeByZXingNet(string strMessage, Int32 width, Int32 height)
        {
            Bitmap result = null;

            try
            {
                BarcodeWriter barCodeWriter = new BarcodeWriter();
                barCodeWriter.Format = BarcodeFormat.QR_CODE;
                barCodeWriter.Options.Hints.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
                barCodeWriter.Options.Hints.Add(EncodeHintType.ERROR_CORRECTION, ZXing.QrCode.Internal.ErrorCorrectionLevel.H);
                barCodeWriter.Options.Height = height;
                barCodeWriter.Options.Width  = width;
                barCodeWriter.Options.Margin = 0;
                ZXing.Common.BitMatrix bm = barCodeWriter.Encode(strMessage);
                result = barCodeWriter.Write(bm);
            }
            catch (Exception)
            {
                //异常输出
            }
            return(result);
        }
Example #25
0
      /// <summary>
      /// <p>Decodes a PDF417 Code represented as a <see cref="BitMatrix" />.
      /// A 1 or "true" is taken to mean a black module.</p>
      ///
      /// <param name="bits">booleans representing white/black PDF417 Code modules</param>
      /// <returns>text and bytes encoded within the PDF417 Code</returns>
      /// <exception cref="FormatException">if the PDF417 Code cannot be decoded</exception>
      /// </summary>
      public DecoderResult decode(BitMatrix bits)
      {
         // Construct a parser to read the data codewords and error-correction level
         BitMatrixParser parser = new BitMatrixParser(bits);
         int[] codewords = parser.readCodewords();
         if (codewords == null || codewords.Length == 0)
         {
            return null;
         }

         int ecLevel = parser.getECLevel();
         int numECCodewords = 1 << (ecLevel + 1);
         int[] erasures = parser.getErasures();

         if (!correctErrors(codewords, erasures, numECCodewords))
            return null;
         if (!verifyCodewordCount(codewords, numECCodewords))
            return null;

         // Decode the codewords
         return DecodedBitStreamParser.decode(codewords);
      }
Example #26
0
      // In case the golden images are not monochromatic, convert the RGB values to greyscale.
      private static BitMatrix createMatrixFromImage(Bitmap image)
      {
         int width = image.Width;
         int height = image.Height;

         var data = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
                                   PixelFormat.Format24bppRgb);
         //image.getRGB(0, 0, width, height, pixels, 0, width);

         BitMatrix matrix = new BitMatrix(width, height);
         try
         {
            unsafe
            {
               for (int y = 0; y < height; y++)
               {
                  var bitmapRow = (byte*)data.Scan0 + (y * data.Stride);
                  for (int x = 0; x < width; x++)
                  {
                     int pixelR = bitmapRow[3 * x + 0];
                     int pixelG = bitmapRow[3 * x + 1];
                     int pixelB = bitmapRow[3 * x + 2];
                     int luminance = (306 * pixelR +
                                      601 * pixelG +
                                      117 * pixelB) >> 10;
                     if (luminance <= 0x7F)
                     {
                        matrix[x, y] = true;
                     }
                  }
               }
            }
         }
         finally
         {
            image.UnlockBits(data);
         }
         return matrix;
      }
Example #27
0
        /// <summary>
        /// decode()
        /// </summary>
        /// <param name="bits"></param>
        /// <param name="hints"></param>
        /// <returns>DecoderResult</returns>
        public DecoderResult decode(BitMatrix bits,
                                    IDictionary<DecodeHintType, object> hints)
        {
            BitMatrixParser parser = new BitMatrixParser(bits);
            byte[] codewords = parser.readCodewords();

            if (!correctErrors(codewords, 0, 10, 10, ALL))
                return null;

            int mode = codewords[0] & 0x0F;
            byte[] datawords;
            switch (mode)
            {
                case 2:
                case 3:
                case 4:
                    if (!correctErrors(codewords, 20, 84, 40, EVEN))
                        return null;
                    if (!correctErrors(codewords, 20, 84, 40, ODD))
                        return null;
                    datawords = new byte[94];
                    break;
                case 5:
                    if (!correctErrors(codewords, 20, 68, 56, EVEN))
                        return null;
                    if (!correctErrors(codewords, 20, 68, 56, ODD))
                        return null;
                    datawords = new byte[78];
                    break;
                default:
                    return null;
            }

            Array.Copy(codewords, 0, datawords, 0, 10);
            Array.Copy(codewords, 20, datawords, 10, datawords.Length - 10);

            return DecodedBitStreamParser.decode(datawords, mode);
        }
Example #28
0
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate (bundle);
            SetContentView (Resource.Layout.qr_generator_activity);
            initGUI ();
            btn_gen.Click += delegate {
                if(!inputText.Text.Equals("")){
                    try{
                    writer = new QRCodeWriter();
                    matrix = writer.encode(inputText.Text, BarcodeFormat.QR_CODE, size, size);

                    int height = matrix.Height;
                    int width = matrix.Width;
                    int[] pixels = new int[width * height];
                    for (int y = 0; y < height; y++)
                    {
                        int offset = y * width;
                        for (int x = 0; x < width; x++)
                        {
                            // pixels[offset + x] = bitMatrix.get(x, y) ? 0xFF000000
                            // : 0xFFFFFFFF;
                            pixels[offset + x] = matrix[x,y] ? Android.Graphics.Color.Black : Android.Graphics.Color.White;
                        }
                    }
                    Bitmap bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);
                    bitmap.SetPixels(pixels, 0, width, 0, 0, width, height);
                    qrCodeView.SetImageBitmap(bitmap);
                    }catch(Exception e){
                        Console.WriteLine(e.StackTrace);
                    }

                }else{
                    Toast.MakeText(this, "Nothing to encode!", ToastLength.Long).Show();
                }
            };
        }
Example #29
0
 private static bool moduleSize(int[] leftTopBlack, BitMatrix image, out float msize)
 {
    int height = image.Height;
    int width = image.Width;
    int x = leftTopBlack[0];
    int y = leftTopBlack[1];
    bool inBlack = true;
    int transitions = 0;
    while (x < width && y < height)
    {
       if (inBlack != image[x, y])
       {
          if (++transitions == 5)
          {
             break;
          }
          inBlack = !inBlack;
       }
       x++;
       y++;
    }
    if (x == width || y == height)
    {
       msize = 0.0f;
       return false;
    }
    msize = (x - leftTopBlack[0]) / 7.0f;
    return true;
 }
Example #30
0
      /// <summary>
      /// This method detects a code in a "pure" image -- that is, pure monochrome image
      /// which contains only an unrotated, unskewed, image of a code, with some white border
      /// around it. This is a specialized method that works exceptionally fast in this special
      /// case.
      /// 
      /// <seealso cref="ZXing.PDF417.PDF417Reader.extractPureBits(BitMatrix)" />
      /// <seealso cref="ZXing.Datamatrix.DataMatrixReader.extractPureBits(BitMatrix)" />
      /// </summary>
      private static BitMatrix extractPureBits(BitMatrix image)
      {
         int[] leftTopBlack = image.getTopLeftOnBit();
         int[] rightBottomBlack = image.getBottomRightOnBit();
         if (leftTopBlack == null || rightBottomBlack == null)
         {
            return null;
         }

         float moduleSize;
         if (!QRCodeReader.moduleSize(leftTopBlack, image, out moduleSize))
            return null;

         int top = leftTopBlack[1];
         int bottom = rightBottomBlack[1];
         int left = leftTopBlack[0];
         int right = rightBottomBlack[0];

         if (bottom - top != right - left)
         {
            // Special case, where bottom-right module wasn't black so we found something else in the last row
            // Assume it's a square, so use height as the width
            right = left + (bottom - top);
         }

         int matrixWidth = (int)Math.Round((right - left + 1) / moduleSize);
         int matrixHeight = (int)Math.Round((bottom - top + 1) / moduleSize);
         if (matrixWidth <= 0 || matrixHeight <= 0)
         {
            return null;
         }
         if (matrixHeight != matrixWidth)
         {
            // Only possibly decode square regions
            return null;
         }

         // Push in the "border" by half the module width so that we start
         // sampling in the middle of the module. Just in case the image is a
         // little off, this will help recover.
         int nudge = (int)(moduleSize / 2.0f);
         top += nudge;
         left += nudge;

         // Now just read off the bits
         BitMatrix bits = new BitMatrix(matrixWidth, matrixHeight);
         for (int y = 0; y < matrixHeight; y++)
         {
            int iOffset = top + (int)(y * moduleSize);
            for (int x = 0; x < matrixWidth; x++)
            {
               if (image[left + (int)(x * moduleSize), iOffset])
               {
                  bits[x, y] = true;
               }
            }
         }
         return bits;
      }
Example #31
0
        /// <summary>
        /// parse()
        /// </summary>
        /// <param name="stringRepresentation"></param>
        /// <param name="setString"></param>
        /// <param name="unsetString"></param>
        /// <returns></returns>
        public static BitMatrix parse(String stringRepresentation, String setString, String unsetString)
        {
            if (stringRepresentation == null)
            {
                throw new ArgumentException();
            }

            bool[] bits        = new bool[stringRepresentation.Length];
            int    bitsPos     = 0;
            int    rowStartPos = 0;
            int    rowLength   = -1;
            int    nRows       = 0;
            int    pos         = 0;

            while (pos < stringRepresentation.Length)
            {
                if (stringRepresentation.Substring(pos, 1).Equals("\n") ||
                    stringRepresentation.Substring(pos, 1).Equals("\r"))
                {
                    if (bitsPos > rowStartPos)
                    {
                        if (rowLength == -1)
                        {
                            rowLength = bitsPos - rowStartPos;
                        }
                        else if (bitsPos - rowStartPos != rowLength)
                        {
                            throw new ArgumentException("row lengths do not match");
                        }
                        rowStartPos = bitsPos;
                        nRows++;
                    }
                    pos++;
                }
                else if (stringRepresentation.Substring(pos, setString.Length).Equals(setString))
                {
                    pos          += setString.Length;
                    bits[bitsPos] = true;
                    bitsPos++;
                }
                else if (stringRepresentation.Substring(pos, unsetString.Length).Equals(unsetString))
                {
                    pos          += unsetString.Length;
                    bits[bitsPos] = false;
                    bitsPos++;
                }
                else
                {
                    throw new ArgumentException("illegal character encountered: " + stringRepresentation.Substring(pos));
                }
            }

            // no EOL at end?
            if (bitsPos > rowStartPos)
            {
                if (rowLength == -1)
                {
                    rowLength = bitsPos - rowStartPos;
                }
                else if (bitsPos - rowStartPos != rowLength)
                {
                    throw new ArgumentException("row lengths do not match");
                }
                nRows++;
            }

            BitMatrix matrix = new BitMatrix(rowLength, nRows);

            for (int i = 0; i < bitsPos; i++)
            {
                if (bits[i])
                {
                    matrix[i % rowLength, i / rowLength] = true;
                }
            }
            return(matrix);
        }
 /// <summary>
 /// Adjusts the codeword start column.
 /// </summary>
 /// <returns>The codeword start column.</returns>
 /// <param name="image">Image.</param>
 /// <param name="minColumn">Minimum column.</param>
 /// <param name="maxColumn">Max column.</param>
 /// <param name="leftToRight">If set to <c>true</c> left to right.</param>
 /// <param name="codewordStartColumn">Codeword start column.</param>
 /// <param name="imageRow">Image row.</param>
 private static int adjustCodewordStartColumn(BitMatrix image,
                                              int minColumn,
                                              int maxColumn,
                                              bool leftToRight,
                                              int codewordStartColumn,
                                              int imageRow)
 {
    int correctedStartColumn = codewordStartColumn;
    int increment = leftToRight ? -1 : 1;
    // there should be no black pixels before the start column. If there are, then we need to start earlier.
    for (int i = 0; i < 2; i++)
    {
       while (((leftToRight && correctedStartColumn >= minColumn) || (!leftToRight && correctedStartColumn < maxColumn)) &&
              leftToRight == image[correctedStartColumn, imageRow])
       {
          if (Math.Abs(codewordStartColumn - correctedStartColumn) > CODEWORD_SKEW_SIZE)
          {
             return codewordStartColumn;
          }
          correctedStartColumn += increment;
       }
       increment = -increment;
       leftToRight = !leftToRight;
    }
    return correctedStartColumn;
 }
 /// <summary>
 /// Gets the module bit count.
 /// </summary>
 /// <returns>The module bit count.</returns>
 /// <param name="image">Image.</param>
 /// <param name="minColumn">Minimum column.</param>
 /// <param name="maxColumn">Max column.</param>
 /// <param name="leftToRight">If set to <c>true</c> left to right.</param>
 /// <param name="startColumn">Start column.</param>
 /// <param name="imageRow">Image row.</param>
 private static int[] getModuleBitCount(BitMatrix image,
                                        int minColumn,
                                        int maxColumn,
                                        bool leftToRight,
                                        int startColumn,
                                        int imageRow)
 {
    int imageColumn = startColumn;
    int[] moduleBitCount = new int[8];
    int moduleNumber = 0;
    int increment = leftToRight ? 1 : -1;
    bool previousPixelValue = leftToRight;
    while (((leftToRight && imageColumn < maxColumn) || (!leftToRight && imageColumn >= minColumn)) &&
           moduleNumber < moduleBitCount.Length)
    {
       if (image[imageColumn, imageRow] == previousPixelValue)
       {
          moduleBitCount[moduleNumber]++;
          imageColumn += increment;
       }
       else
       {
          moduleNumber++;
          previousPixelValue = !previousPixelValue;
       }
    }
    if (moduleNumber == moduleBitCount.Length ||
        (((leftToRight && imageColumn == maxColumn) || (!leftToRight && imageColumn == minColumn)) && moduleNumber == moduleBitCount.Length - 1))
    {
       return moduleBitCount;
    }
    return null;
 }
      /// <summary>
      /// Detects the codeword.
      /// </summary>
      /// <returns>The codeword.</returns>
      /// <param name="image">Image.</param>
      /// <param name="minColumn">Minimum column.</param>
      /// <param name="maxColumn">Max column.</param>
      /// <param name="leftToRight">If set to <c>true</c> left to right.</param>
      /// <param name="startColumn">Start column.</param>
      /// <param name="imageRow">Image row.</param>
      /// <param name="minCodewordWidth">Minimum codeword width.</param>
      /// <param name="maxCodewordWidth">Max codeword width.</param>
      private static Codeword detectCodeword(BitMatrix image,
                                             int minColumn,
                                             int maxColumn,
                                             bool leftToRight,
                                             int startColumn,
                                             int imageRow,
                                             int minCodewordWidth,
                                             int maxCodewordWidth)
      {
         startColumn = adjustCodewordStartColumn(image, minColumn, maxColumn, leftToRight, startColumn, imageRow);
         // we usually know fairly exact now how long a codeword is. We should provide minimum and maximum expected length
         // and try to adjust the read pixels, e.g. remove single pixel errors or try to cut off exceeding pixels.
         // min and maxCodewordWidth should not be used as they are calculated for the whole barcode an can be inaccurate
         // for the current position
         int[] moduleBitCount = getModuleBitCount(image, minColumn, maxColumn, leftToRight, startColumn, imageRow);
         if (moduleBitCount == null)
         {
            return null;
         }
         int endColumn;
         int codewordBitCount = PDF417Common.getBitCountSum(moduleBitCount);
         if (leftToRight)
         {
            endColumn = startColumn + codewordBitCount;
         }
         else
         {
            for (int i = 0; i < (moduleBitCount.Length >> 1); i++)
            {
               int tmpCount = moduleBitCount[i];
               moduleBitCount[i] = moduleBitCount[moduleBitCount.Length - 1 - i];
               moduleBitCount[moduleBitCount.Length - 1 - i] = tmpCount;
            }
            endColumn = startColumn;
            startColumn = endColumn - codewordBitCount;
         }
         // TODO implement check for width and correction of black and white bars
         // use start (and maybe stop pattern) to determine if blackbars are wider than white bars. If so, adjust.
         // should probably done only for codewords with a lot more than 17 bits. 
         // The following fixes 10-1.png, which has wide black bars and small white bars
         //    for (int i = 0; i < moduleBitCount.Length; i++) {
         //      if (i % 2 == 0) {
         //        moduleBitCount[i]--;
         //      } else {
         //        moduleBitCount[i]++;
         //      }
         //    }

         // We could also use the width of surrounding codewords for more accurate results, but this seems
         // sufficient for now
         if (!checkCodewordSkew(codewordBitCount, minCodewordWidth, maxCodewordWidth))
         {
            // We could try to use the startX and endX position of the codeword in the same column in the previous row,
            // create the bit count from it and normalize it to 8. This would help with single pixel errors.
            return null;
         }

         int decodedValue = PDF417CodewordDecoder.getDecodedValue(moduleBitCount);
         int codeword = PDF417Common.getCodeword(decodedValue);
         if (codeword == -1)
         {
            return null;
         }
         return new Codeword(startColumn, endColumn, getCodewordBucketNumber(decodedValue), codeword);
      }
      /// <summary>
      /// Decode the specified image, imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight, minCodewordWidth
      /// and maxCodewordWidth.
      /// TODO: don't pass in minCodewordWidth and maxCodewordWidth, pass in barcode columns for start and stop pattern
      /// columns. That way width can be deducted from the pattern column.
      /// This approach also allows to detect more details about the barcode, e.g. if a bar type (white or black) is wider 
      /// than it should be. This can happen if the scanner used a bad blackpoint.
      /// </summary>
      /// <param name="image">Image.</param>
      /// <param name="imageTopLeft">Image top left.</param>
      /// <param name="imageBottomLeft">Image bottom left.</param>
      /// <param name="imageTopRight">Image top right.</param>
      /// <param name="imageBottomRight">Image bottom right.</param>
      /// <param name="minCodewordWidth">Minimum codeword width.</param>
      /// <param name="maxCodewordWidth">Max codeword width.</param>
      public static DecoderResult decode(BitMatrix image,
                                         ResultPoint imageTopLeft,
                                         ResultPoint imageBottomLeft,
                                         ResultPoint imageTopRight,
                                         ResultPoint imageBottomRight,
                                         int minCodewordWidth,
                                         int maxCodewordWidth)
      {
         BoundingBox boundingBox = BoundingBox.Create(image, imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight);
         if (boundingBox == null)
            return null;

         DetectionResultRowIndicatorColumn leftRowIndicatorColumn = null;
         DetectionResultRowIndicatorColumn rightRowIndicatorColumn = null;
         DetectionResult detectionResult = null;
         for (int i = 0; i < 2; i++)
         {
            if (imageTopLeft != null)
            {
               leftRowIndicatorColumn = getRowIndicatorColumn(image, boundingBox, imageTopLeft, true, minCodewordWidth, maxCodewordWidth);
            }
            if (imageTopRight != null)
            {
               rightRowIndicatorColumn = getRowIndicatorColumn(image, boundingBox, imageTopRight, false, minCodewordWidth, maxCodewordWidth);
            }
            detectionResult = merge(leftRowIndicatorColumn, rightRowIndicatorColumn);
            if (detectionResult == null)
            {
               // TODO Based on Owen's Comments in <see cref="ZXing.ReaderException"/>, this method has been modified to continue silently
               // if a barcode was not decoded where it was detected instead of throwing a new exception object.
               return null;
            }
            if (i == 0 && detectionResult.Box != null &&
                (detectionResult.Box.MinY < boundingBox.MinY || detectionResult.Box.MaxY > boundingBox.MaxY))
            {
               boundingBox = detectionResult.Box;
            }
            else
            {
               detectionResult.Box = boundingBox;
               break;
            }
         }
         int maxBarcodeColumn = detectionResult.ColumnCount + 1;
         detectionResult.DetectionResultColumns[0] = leftRowIndicatorColumn;

         detectionResult.DetectionResultColumns[maxBarcodeColumn] = rightRowIndicatorColumn;

         bool leftToRight = leftRowIndicatorColumn != null;
         for (int barcodeColumnCount = 1; barcodeColumnCount <= maxBarcodeColumn; barcodeColumnCount++)
         {
            int barcodeColumn = leftToRight ? barcodeColumnCount : maxBarcodeColumn - barcodeColumnCount;
            if (detectionResult.DetectionResultColumns[barcodeColumn] != null)
            {
               // This will be the case for the opposite row indicator column, which doesn't need to be decoded again.
               continue;
            }
            DetectionResultColumn detectionResultColumn;
            if (barcodeColumn == 0 || barcodeColumn == maxBarcodeColumn)
            {
               detectionResultColumn = new DetectionResultRowIndicatorColumn(boundingBox, barcodeColumn == 0);
            }
            else
            {
               detectionResultColumn = new DetectionResultColumn(boundingBox);
            }
            detectionResult.DetectionResultColumns[barcodeColumn] = detectionResultColumn;
            int startColumn = -1;
            int previousStartColumn = startColumn;
            // TODO start at a row for which we know the start position, then detect upwards and downwards from there.
            for (int imageRow = boundingBox.MinY; imageRow <= boundingBox.MaxY; imageRow++)
            {
               startColumn = getStartColumn(detectionResult, barcodeColumn, imageRow, leftToRight);
               if (startColumn < 0 || startColumn > boundingBox.MaxX)
               {
                  if (previousStartColumn == -1)
                  {
                     continue;
                  }
                  startColumn = previousStartColumn;
               }
               Codeword codeword = detectCodeword(image, boundingBox.MinX, boundingBox.MaxX, leftToRight,
                                                  startColumn, imageRow, minCodewordWidth, maxCodewordWidth);
               if (codeword != null)
               {
                  detectionResultColumn.setCodeword(imageRow, codeword);
                  previousStartColumn = startColumn;
                  minCodewordWidth = Math.Min(minCodewordWidth, codeword.Width);
                  maxCodewordWidth = Math.Max(maxCodewordWidth, codeword.Width);
               }
            }
         }
         return createDecoderResult(detectionResult);
      }
 /// <summary>
 /// Gets the row indicator column.
 /// </summary>
 /// <returns>The row indicator column.</returns>
 /// <param name="image">Image.</param>
 /// <param name="boundingBox">Bounding box.</param>
 /// <param name="startPoint">Start point.</param>
 /// <param name="leftToRight">If set to <c>true</c> left to right.</param>
 /// <param name="minCodewordWidth">Minimum codeword width.</param>
 /// <param name="maxCodewordWidth">Max codeword width.</param>
 private static DetectionResultRowIndicatorColumn getRowIndicatorColumn(BitMatrix image,
                                                                        BoundingBox boundingBox,
                                                                        ResultPoint startPoint,
                                                                        bool leftToRight,
                                                                        int minCodewordWidth,
                                                                        int maxCodewordWidth)
 {
    DetectionResultRowIndicatorColumn rowIndicatorColumn = new DetectionResultRowIndicatorColumn(boundingBox, leftToRight);
    for (int i = 0; i < 2; i++)
    {
       int increment = i == 0 ? 1 : -1;
       int startColumn = (int) startPoint.X;
       for (int imageRow = (int) startPoint.Y; imageRow <= boundingBox.MaxY &&
                                               imageRow >= boundingBox.MinY; imageRow += increment)
       {
          Codeword codeword = detectCodeword(image, 0, image.Width, leftToRight, startColumn, imageRow,
                                             minCodewordWidth, maxCodewordWidth);
          if (codeword != null)
          {
             rowIndicatorColumn.setCodeword(imageRow, codeword);
             if (leftToRight)
             {
                startColumn = codeword.StartX;
             }
             else
             {
                startColumn = codeword.EndX;
             }
          }
       }
    }
    return rowIndicatorColumn;
 }
        /// <summary>
        /// 生成带Logo的二维码
        /// </summary>
        /// <param name="text">文本内容</param>
        public static void Generate(string text, string LogoPth, string serverPth, string filename, ImgType type, /* ImageFormat imgFrt,*/ int?width = null, int?hight = null)
        {
            try
            {
                //Logo 图片
                Bitmap logo = new Bitmap(LogoPth);
                //构造二维码写码器
                MultiFormatWriter writer = new MultiFormatWriter();
                Dictionary <EncodeHintType, object> hint = new Dictionary <EncodeHintType, object>();
                hint.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
                hint.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

                int w = 300;
                int h = 300;
                if (width != null)
                {
                    w = (int)width;
                }
                if (hight != null)
                {
                    h = (int)hight;
                }
                //生成二维码
                ZXing.Common.BitMatrix bm            = writer.encode(text, BarcodeFormat.QR_CODE, w, h, hint);
                BarcodeWriter          barcodeWriter = new BarcodeWriter();
                Bitmap map = barcodeWriter.Write(bm);


                //获取二维码实际尺寸(去掉二维码两边空白后的实际尺寸)
                int[] rectangle = bm.getEnclosingRectangle();

                //计算插入图片的大小和位置
                int middleW = Math.Min((int)(rectangle[2] / 3.5), logo.Width);
                int middleH = Math.Min((int)(rectangle[3] / 3.5), logo.Height);
                int middleL = (map.Width - middleW) / 2;
                int middleT = (map.Height - middleH) / 2;

                //将img转换成bmp格式,否则后面无法创建Graphics对象
                Bitmap bmpimg = new Bitmap(map.Width, map.Height, PixelFormat.Format32bppArgb);
                using (Graphics g = Graphics.FromImage(bmpimg))
                {
                    g.InterpolationMode  = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode      = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    g.DrawImage(map, 0, 0);
                }
                //将二维码插入图片
                Graphics myGraphic = Graphics.FromImage(bmpimg);
                //白底
                myGraphic.FillRectangle(Brushes.White, middleL, middleT, middleW, middleH);
                myGraphic.DrawImage(logo, middleL, middleT, middleW, middleH);
                string suffix = ImgSuffix.Getsuffix(type);; //后缀
                if (!Directory.Exists(serverPth))
                {
                    Directory.CreateDirectory(serverPth);
                }
                //保存成图片
                bmpimg.Save($"{serverPth}{filename}{suffix}");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }