예제 #1
0
        /// <summary>
        ///         Trả về link ảnh từ dịch vụ QRCode của Google
        /// </summary>
        /// <param name="Text">Văn bản cần sinh mã QR</param>
        /// <param name="ImageSize">Kích thước của ảnh QR. Tối đa là 500 px</param>
        /// <param name="Correction">Mức độ chịu lỗi</param>
        /// <param name="Margin">Số điểm ảnh trắng để làm biên </param>
        /// <returns></returns>
        static string GetQRCodeWebAPI(string Text, int ImageSize = 500, CorrectionLevel Correction = CorrectionLevel.High, int Margin = 0)
        {
            StringBuilder sURL = new StringBuilder();

            sURL.AppendFormat("https://chart.googleapis.com/chart?cht=qr&chs={0}x{0}&chld={1}|{2}&chl={3}", ImageSize, Correction, Margin, Text);
            return(sURL.ToString());
        }
예제 #2
0
        public static DataBlock BlockMaker(string data, CorrectionLevel level, int version)
        {
            var d   = new StringBuilder(data);
            var res = BlockStrToBlockInt(d);

            return(new DataBlock(res.ToList(), level, version));
        }
예제 #3
0
파일: BarCodes.cs 프로젝트: Yusim/BarIn
 private static byte[] CodingByte(byte[] Bytes, int Version, CorrectionLevel Level)
 {
     #region Кодирование (Data)
     BitSequence Data = new BitSequence(Bytes);
     #endregion
     #region Добавление служебных полей (DataTmp)
     int         MaxLength  = MaxCapacity[(int)Level, Version - 1];
     BitSequence TypeCode   = new BitSequence(new bool[] { false, true, false, false });
     byte[]      BytesCount =
         (Version < 10
         ? new byte[] { (byte)(Bytes.Length & 0x00FF) }
         : new byte[] { (byte)((Bytes.Length & 0xFF00) >> 8), (byte)(Bytes.Length & 0x00FF) });
     BitSequence DataLength = new BitSequence(BytesCount);
     BitSequence ResultBits = TypeCode + DataLength + Data;
     if (ResultBits.Length > MaxLength)
     {
         throw new Exception(ErrorLongData);
     }
     byte[] DataTmp = ResultBits.ToByteArray();
     #endregion
     #region Дополнение (Result)
     byte[] Result = new byte[MaxLength / 8];
     DataTmp.CopyTo(Result, 0);
     bool f = true;
     for (int i = DataTmp.Length; i < Result.Length; i++)
     {
         Result[i] = (f ? (byte)0b11101100 : (byte)0b00010001);
         f         = !f;
     }
     #endregion
     return(Result);
 }
예제 #4
0
        private static int GetVersion(CorrectionLevel level, int dataLenght)
        {
            for (var i = 0; i < TableOfVersions.AmountInfoForVersion[level].Length; i++) // TODO тут нужно использовать сортировку
            {
                if (dataLenght < TableOfVersions.AmountInfoForVersion[level][i])
                {
                    return(i);
                }
            }

            throw new NullReferenceException("level not exist");
        }
예제 #5
0
        /// <summary>
        /// Method GetCorrectionBlocks creates corrections blocks
        /// </summary>
        /// <param name="dataBlocks">blocks containing data</param>
        /// <param name="correctionLevel">correction level</param>
        /// <param name="version">version number</param>
        /// <returns>Returns array containing corrections blocks </returns>
        internal static byte[][] GetCorrectionBlocks(byte[][] dataBlocks, CorrectionLevel correctionLevel, int version)
        {
            byte[][] correctionBlocks;
            int      countBytes = GetCountBytes(correctionLevel, version);

            byte[] polinomial = polinomials[countBytes];
            correctionBlocks = new byte[dataBlocks.Length][];
            for (int i = 0; i < correctionBlocks.Length; i++)
            {
                correctionBlocks[i] = GetCorrectionBlock(dataBlocks[i], polinomial);
            }
            return(correctionBlocks);
        }
예제 #6
0
        /// <summary>
        /// Method DivideByBlocks dividing data by blocks
        /// </summary>
        /// <param name="data"></param>
        /// <param name="correctionLevel"></param>
        /// <param name="version"></param>
        /// <returns>Returns data divided by blocks</returns>
        internal static byte[][] DivideByBlocks(byte[] data, CorrectionLevel correctionLevel, int version)
        {
            byte[][] dataBlocks;
            int      blocksCount = GetBlocksCount(correctionLevel, version);

            dataBlocks = new byte[blocksCount][];
            int[] blocksLengths = GetBlocksLengths(blocksCount, data.Length);
            for (int i = 0; i < dataBlocks.Length; i++)
            {
                dataBlocks[i] = new byte[blocksLengths[i]];
            }
            dataBlocks = DataCombiner.FillingBlocks(data, dataBlocks);
            return(dataBlocks);
        }
예제 #7
0
        private static string ComplementUpToVersion(string str, CorrectionLevel level, int version)
        {
            const string first            = "11101100";
            const string second           = "00010001";
            var          s                = new StringBuilder();
            var          fullBite         = TableOfVersions.AmountInfoForVersion[level][version];
            var          needToComplement = fullBite - str.Length;

            for (var i = 0; i < needToComplement / 8; i++)
            {
                s.Append(i % 2 == 0 ? first : second);
            }

            return(str + s);
        }
예제 #8
0
        private static string Split(string data, CorrectionLevel level, int version, int countOfBlock,
                                    int dataInOneBlock, ICollection <DataBlock> list, int k)
        {
            for (var i = 0; i < countOfBlock; i++)
            {
                list.Add(BlockMaker(data.Substring(0, dataInOneBlock * k), level, version));
                if (dataInOneBlock - 1 != data.Length - 1)
                {
                    data = data.Substring(dataInOneBlock * k - 1, data.Length - dataInOneBlock * k);
                }
                else
                {
                    break;
                }
            }

            return(data);
        }
예제 #9
0
파일: BarCodes.cs 프로젝트: Yusim/BarIn
        private static byte[] Correct(byte[] Block, int Version, CorrectionLevel Level)
        {
            int CorrSize = CorrByteCount[(int)Level, Version - 1];

            byte[] tmp = new byte[Math.Max(CorrSize, Block.Length)];
            Block.CopyTo(tmp, 0);
            for (int i = Block.Length; i < tmp.Length; i++)
            {
                tmp[i] = 0;
            }
            for (int cnt = 0; cnt < Block.Length; cnt++)
            {
                byte a = tmp[0];
                for (int i = 1; i < tmp.Length; i++)
                {
                    tmp[i - 1] = tmp[i];
                }
                tmp[tmp.Length - 1] = 0;
                if (a != 0)
                {
                    byte   b = TabGaluaDesc[a];
                    byte[] g = new byte[CorrSize];
                    for (int i = 0; i < g.Length; i++)
                    {
                        g[i] = (byte)((Polinom[CorrSize][i] + b) % 255);
                    }
                    for (int i = 0; i < g.Length; i++)
                    {
                        g[i] = TabGalua[g[i]];
                    }
                    for (int i = 0; i < g.Length; i++)
                    {
                        tmp[i] = (byte)(tmp[i] ^ g[i]);
                    }
                }
            }
            byte[] Result = new byte[CorrSize];
            for (int i = 0; i < CorrSize; i++)
            {
                Result[i] = tmp[i];
            }
            return(Result);
        }
예제 #10
0
파일: BarCodes.cs 프로젝트: Yusim/BarIn
        private static byte[][] BlockCreate(byte[] Data, int Version, CorrectionLevel Level)
        {
            int nBlock = BlockCount[(int)Level, Version - 1];

            byte[][] Result = new byte[nBlock][];
            int      size   = Data.Length / nBlock;
            int      md     = (Data.Length % nBlock);
            int      ind    = 0;

            for (int i = 0; i < nBlock; i++)
            {
                Result[i] = new byte[(i >= nBlock - md ? size + 1 : size)];
                for (int j = 0; j < Result[i].Length; j++)
                {
                    Result[i][j] = Data[ind];
                    ind++;
                }
            }
            return(Result);
        }
예제 #11
0
        /// <summary>
        /// Method GetCapacities returns array of capacities by correction level
        /// </summary>
        /// <returns>Return array of capacities</returns>
        private int[] GetCapacities(CorrectionLevel correctionLevel)
        {
            switch (correctionLevel)
            {
            case CorrectionLevel.L:
                return(capacitiesL);

            case CorrectionLevel.M:
                return(capacitiesM);

            case CorrectionLevel.Q:
                return(capacitiesQ);

            case CorrectionLevel.H:
                return(capacitiesH);

            default:
                return(default);
            }
        }
예제 #12
0
        /// <summary>
        /// Method GetBlockCount get count of data blocks by correction level
        /// </summary>
        /// <param name="correctionLevel"></param>
        /// <param name="version"></param>
        /// <returns>Return count of data blocks</returns>
        private static int GetBlocksCount(CorrectionLevel correctionLevel, int version)
        {
            switch (correctionLevel)
            {
            case CorrectionLevel.L:
                return(blocksCountL[version - 1]);

            case CorrectionLevel.M:
                return(blocksCountM[version - 1]);

            case CorrectionLevel.Q:
                return(blocksCountQ[version - 1]);

            case CorrectionLevel.H:
                return(blocksCountH[version - 1]);

            default:
                return(default);
            }
        }
예제 #13
0
        /// <summary>
        /// Method GetCountBytes returns count of correction bytes by version
        /// </summary>
        /// <param name="correctionLevel">correction level</param>
        /// <param name="version">version</param>
        /// <returns>Returns count of correction bytes</returns>
        private static int GetCountBytes(CorrectionLevel correctionLevel, int version)
        {
            switch (correctionLevel)
            {
            case CorrectionLevel.L:
                return(countBytesL[version - 1]);

            case CorrectionLevel.M:
                return(countBytesM[version - 1]);

            case CorrectionLevel.Q:
                return(countBytesQ[version - 1]);

            case CorrectionLevel.H:
                return(countBytesH[version - 1]);

            default:
                return(0);
            }
        }
예제 #14
0
파일: BarCodes.cs 프로젝트: Yusim/BarIn
 private static byte[] DataStream(byte[][] Blocks, int Version, CorrectionLevel Level)
 {
     #region Создание блоков коррекции
     byte[][] CorrBlocks = new byte[Blocks.Length][];
     for (int i = 0; i < CorrBlocks.Length; i++)
     {
         CorrBlocks[i] = Correct(Blocks[i], Version, Level);
     }
     #endregion
     #region Объединение блоков
     List <byte> Result   = new List <byte>();
     int         MaxBlock = (from x in Blocks select x.Length).Max();
     for (int i = 0; i < MaxBlock; i++)
     {
         for (int j = 0; j < Blocks.Length; j++)
         {
             if (i < Blocks[j].Length)
             {
                 Result.Add(Blocks[j][i]);
             }
         }
     }
     int MaxCorr = (from x in CorrBlocks select x.Length).Max();
     for (int i = 0; i < MaxCorr; i++)
     {
         for (int j = 0; j < CorrBlocks.Length; j++)
         {
             if (i < CorrBlocks[j].Length)
             {
                 Result.Add(CorrBlocks[j][i]);
             }
         }
     }
     #endregion
     return(Result.ToArray());
 }
예제 #15
0
        /// <summary>
        /// Method AddMaskCode adds mask code on the QRCode template
        /// </summary>
        /// <param name="template">QR code template</param>
        /// <param name="correctionLevel">QR code correction level</param>
        /// <param name="maskId">QR code mask id</param>
        private void AddMaskCode(byte[,] template, CorrectionLevel correctionLevel, int maskId)
        {
            int schemeSize = template.GetLength(0) - 1;
            int point      = 0;

            byte[] mask;

            mask = GetMaskCode(correctionLevel, maskId);
            for (int i = 0; i < 8; i++)
            {
                if (i == 6)
                {
                    point++;
                }
                template[8, point] = mask[i];
                template[point, 8] = mask[mask.Length - 1 - i];
                point++;

                template[schemeSize - i, 8] = mask[i];
                template[8, schemeSize - i] = mask[mask.Length - 1 - i];
            }

            template[schemeSize - 7, 8] = 1;
        }
예제 #16
0
        /// <summary>
        /// Method GetMaskCode gets QR code mask as bit sequence
        /// </summary>
        /// <param name="correctionLevel">QR code correction level</param>
        /// <param name="maskId">QR code mask id</param>
        /// <returns>Returns mask as bit sequence</returns>
        private byte[] GetMaskCode(CorrectionLevel correctionLevel, int maskId)
        {
            if (maskId > 7)
            {
                maskId = 0;
            }
            switch (correctionLevel)
            {
            case CorrectionLevel.L:
                return(maskCodesL[maskId]);

            case CorrectionLevel.M:
                return(maskCodesM[maskId]);

            case CorrectionLevel.Q:
                return(maskCodesQ[maskId]);

            case CorrectionLevel.H:
                return(maskCodesH[maskId]);

            default:
                return(default);
            }
        }
예제 #17
0
 public void WriteQR(QRType type, CorrectionLevel correction, string s)
 {
     DeedeeDocWriteQR(ptr, (int)type, (int)correction, s);
 }
예제 #18
0
 public ServiceData(CodingType type, CorrectionLevel level)
 {
     CorrectionLevel = level;
     CodingType      = type;
 }
예제 #19
0
 public Data(string data, CorrectionLevel level, Func <string, string> encode, string codingType)
 {
     DataBit    = encode(data);
     Level      = level;
     CodingType = codingType;
 }
예제 #20
0
        /// <summary>
        ///         Trả về file name (path) của ảnh tạo ra bởi ZXing library (temp file)
        /// </summary>
        /// <param name="Text">Văn bản cần sinh mã QR</param>
        /// <param name="ImageSize">Kích thước của ảnh QR. Tối đa là 500 px</param>
        /// <param name="Correction">Mức độ chịu lỗi</param>
        /// <param name="Margin">Số điểm ảnh trắng để làm biên </param>
        /// <returns></returns>
        static string GetQRCodeLocalFileNameByZXing(string Text, int ImageSize = 500, CorrectionLevel Correction = CorrectionLevel.High, int Margin = 0)
        {
            QRCodeWriter qr = new ZXing.QrCode.QRCodeWriter(); //QRCode as a BitMatrix 2D array

            Dictionary <EncodeHintType, object> hint = new Dictionary <EncodeHintType, object>();

            hint.Add(EncodeHintType.MARGIN, Margin); // margin of the QRCode image
            hint.Add(EncodeHintType.ERROR_CORRECTION, Correction);

            var matrix = qr.encode(Text, BarcodeFormat.QR_CODE, ImageSize, ImageSize, hint); // encode QRCode matrix from source text

            ZXing.BarcodeWriter w = new ZXing.BarcodeWriter();
            Bitmap img            = w.Write(matrix);                    // QRCode Bitmap image
            string tempFile       = Path.GetTempFileName();             //create a temp file to save QRCode image

            img.Save(tempFile, System.Drawing.Imaging.ImageFormat.Png); //save QRCode image to temp file

            return(tempFile);
        }
예제 #21
0
파일: BarCodes.cs 프로젝트: Yusim/BarIn
 /// <summary>
 /// Создание QR кода
 /// </summary>
 /// <param name="Bytes">Кодируемая последовательность</param>
 /// <param name="Version">Номер версии (определяет размер)</param>
 /// <param name="Level">Уровень коррекции</param>
 /// <param name="MaskCode">Код маски ("-1" - оптимальная)</param>
 /// <param name="Zoom">Размер квадратиков в пикселах</param>
 /// <returns>QR код</returns>
 public static Bitmap CreateQR(byte[] Bytes, int Version, CorrectionLevel Level, int MaskCode, int Zoom)
 {
     #region Проверка параметров
     if (Bytes == null)
     {
         throw new ArgumentNullException(ErrorNullData);
     }
     if ((Version < 1) || (Version > 40))
     {
         throw new Exception(ErrorBadVersion);
     }
     if (((int)Level < 0) || ((int)Level > 3))
     {
         throw new Exception(ErrorBadLevel);
     }
     if ((MaskCode < -1) || (MaskCode > 7))
     {
         throw new Exception(ErrorBadMask);
     }
     if (Zoom < 1)
     {
         throw new Exception(ErrorZoom);
     }
     #endregion
     #region Получение конечного потока данных (byte[] Data)
     byte[]   cBytes = CodingByte(Bytes, Version, Level);
     byte[][] bData  = BlockCreate(cBytes, Version, Level);
     byte[]   Data   = DataStream(bData, Version, Level);
     #endregion
     #region Выбор маски
     bool[,] Mtx;
     if (MaskCode == -1)
     {
         Mtx = CreateMatrix(Data, Version, Level, 0);
         int r = RateMatrix(Mtx);
         for (int i = 1; i < 8; i++)
         {
             bool[,] m = CreateMatrix(Data, Version, Level, i);
             int n = RateMatrix(m);
             if (n < r)
             {
                 Mtx = m;
                 r   = n;
             }
         }
     }
     else
     {
         Mtx = CreateMatrix(Data, Version, Level, MaskCode);
     }
     #endregion
     #region Формирование рисунка
     int      BarSize = Mtx.GetLength(0);
     Bitmap   Result  = new Bitmap((BarSize + 8) * Zoom, (BarSize + 8) * Zoom);
     Graphics g       = Graphics.FromImage(Result);
     g.Clear(Color.White);
     for (int x = 0; x < BarSize; x++)
     {
         for (int y = 0; y < BarSize; y++)
         {
             g.FillRectangle((Mtx[x, y] ? Brushes.Black : Brushes.White), (4 + x) * Zoom, (4 + y) * Zoom, Zoom, Zoom);
         }
     }
     #endregion
     return(Result);
 }
예제 #22
0
파일: BarCodes.cs 프로젝트: Yusim/BarIn
        private static bool[,] CreateMatrix(byte[] Data, int Version, CorrectionLevel Level, int MaskCode)
        {
            #region Создание матрицы (bool?[,] Mtx)
            int BarSize = 17 + 4 * Version;
            bool?[,] Mtx = new bool?[BarSize, BarSize];
            for (int i = 0; i < BarSize; i++)
            {
                for (int j = 0; j < BarSize; j++)
                {
                    Mtx[i, j] = null;
                }
            }
            #endregion
            #region Поисковые узоры
            void ProcBox(int x, int y, int l, bool f)
            {
                for (int i = 0; i < l; i++)
                {
                    for (int j = 0; j < l; j++)
                    {
                        Mtx[x + i, y + j] = f;
                    }
                }
            }

            #region Большие квадраты
            void BigBox(int x, int y)
            {
                ProcBox(x, y, 7, true);
                ProcBox(x + 1, y + 1, 5, false);
                ProcBox(x + 2, y + 2, 3, true);
            }

            ProcBox(0, 0, 8, false);
            BigBox(0, 0);
            ProcBox(0, BarSize - 8, 8, false);
            BigBox(0, BarSize - 7);
            ProcBox(BarSize - 8, 0, 8, false);
            BigBox(BarSize - 7, 0);
            #endregion
            #region Малые квадраты
            void SmallBox(int x, int y)
            {
                ProcBox(x, y, 5, true);
                ProcBox(x + 1, y + 1, 3, false);
                ProcBox(x + 2, y + 2, 1, true);
            }

            for (int i = 0; i < AlignPosition[Version - 1].Length; i++)
            {
                for (int j = 0; j < AlignPosition[Version - 1].Length; j++)
                {
                    int x = AlignPosition[Version - 1][i];
                    int y = AlignPosition[Version - 1][j];
                    if (Mtx[x, y] == null)
                    {
                        SmallBox(x - 2, y - 2);
                    }
                }
            }
            #endregion
            #region Полоса
            bool LineFlag = true;
            for (int i = 6; i < BarSize; i++)
            {
                if (Mtx[6, i] == null)
                {
                    Mtx[6, i] = LineFlag;
                }
                if (Mtx[i, 6] == null)
                {
                    Mtx[i, 6] = LineFlag;
                }
                LineFlag = (!LineFlag);
            }
            #endregion
            #endregion
            #region Код версии
            if (Version > 6)
            {
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 6; j++)
                    {
                        Mtx[j, BarSize - 11 + i] = VersionPattern[Version][i][j];
                        Mtx[BarSize - 11 + i, j] = VersionPattern[Version][i][j];
                    }
                }
            }

            #endregion
            #region Код маски и уровня
            BitSequence MaskPatt = MaskLevelPattern[MaskCode, (int)Level];
            Mtx[0, 8]           = MaskPatt[0];
            Mtx[1, 8]           = MaskPatt[1];
            Mtx[2, 8]           = MaskPatt[2];
            Mtx[3, 8]           = MaskPatt[3];
            Mtx[4, 8]           = MaskPatt[4];
            Mtx[5, 8]           = MaskPatt[5];
            Mtx[7, 8]           = MaskPatt[6];
            Mtx[8, 8]           = MaskPatt[7];
            Mtx[8, 7]           = MaskPatt[8];
            Mtx[8, 5]           = MaskPatt[9];
            Mtx[8, 4]           = MaskPatt[10];
            Mtx[8, 3]           = MaskPatt[11];
            Mtx[8, 2]           = MaskPatt[12];
            Mtx[8, 1]           = MaskPatt[13];
            Mtx[8, 0]           = MaskPatt[14];
            Mtx[8, BarSize - 1] = MaskPatt[0];
            Mtx[8, BarSize - 2] = MaskPatt[1];
            Mtx[8, BarSize - 3] = MaskPatt[2];
            Mtx[8, BarSize - 4] = MaskPatt[3];
            Mtx[8, BarSize - 5] = MaskPatt[4];
            Mtx[8, BarSize - 6] = MaskPatt[5];
            Mtx[8, BarSize - 7] = MaskPatt[6];
            Mtx[8, BarSize - 8] = true;
            Mtx[BarSize - 8, 8] = MaskPatt[7];
            Mtx[BarSize - 7, 8] = MaskPatt[8];
            Mtx[BarSize - 6, 8] = MaskPatt[9];
            Mtx[BarSize - 5, 8] = MaskPatt[10];
            Mtx[BarSize - 4, 8] = MaskPatt[11];
            Mtx[BarSize - 3, 8] = MaskPatt[12];
            Mtx[BarSize - 2, 8] = MaskPatt[13];
            Mtx[BarSize - 1, 8] = MaskPatt[14];
            #endregion
            #region Запись данных
            BitSequence stm = new BitSequence(Data);
            int         xx  = BarSize - 1;
            int         yy  = BarSize - 1;
            bool        dx  = false;
            int         dy  = -1;
            for (int n = 0; n < stm.Length; n++)
            {
                #region Выбор следующей ячейки
                while (Mtx[xx, yy] != null)
                {
                    if (xx == 6)
                    {
                        xx--;
                        continue;
                    }
                    if (!dx)
                    {
                        xx--;
                        dx = (!dx);
                        continue;
                    }
                    if ((yy + dy >= 0) && (yy + dy <= BarSize - 1))
                    {
                        xx++;
                        yy += dy;
                        dx  = (!dx);
                        continue;
                    }
                    xx--;
                    dx = (!dx);
                    dy = -dy;
                }
                #endregion
                Mtx[xx, yy] = (stm[n] ^ MaskFunction[MaskCode](xx, yy));
            }
            #endregion
            #region Дозаполнение пустого места
            for (int i = 0; i < BarSize; i++)
            {
                for (int j = 0; j < BarSize; j++)
                {
                    if (Mtx[i, j] == null)
                    {
                        Mtx[i, j] = MaskFunction[MaskCode](i + 1, j + 1);
                    }
                }
            }
            #endregion
            #region Формирование результата
            bool[,] Result = new bool[BarSize, BarSize];
            for (int i = 0; i < BarSize; i++)
            {
                for (int j = 0; j < BarSize; j++)
                {
                    Result[i, j] = (bool)Mtx[i, j];
                }
            }
            #endregion
            return(Result);
        }
예제 #23
0
 public DataBlock(List <int> data, CorrectionLevel level, int version)
 {
     Data = data;
     CountOfCorrectionBytes = GetCount(level, version);
 }
예제 #24
0
 private static int GetCount(CorrectionLevel level, int version)
 {
     return(TableCorrectionBytes.BytesMap[level][version]);
 }
예제 #25
0
 public QRTemplater(CorrectionLevel correctionLevel, int version)
 {
     CorrectionLevel = correctionLevel;
     Version         = version;
 }
예제 #26
0
        /// <summary>
        ///         Trả về file name (path) của ảnh tạo ra bởi ZXing library (temp file)
        /// </summary>
        /// <param name="Text">Văn bản cần sinh mã QR</param>
        /// <param name="ImageSize">Kích thước của ảnh QR. Tối đa là 500 px</param>
        /// <param name="Correction">Mức độ chịu lỗi</param>
        /// <param name="Margin">Số điểm ảnh trắng để làm biên </param>
        /// <returns></returns>
        static string GetQRCodeLocalFileNameByZXing(string Text, int ImageSize = 500, CorrectionLevel Correction = CorrectionLevel.High, int Margin = 0)
        {
            QRCodeWriter qr = new ZXing.QrCode.QRCodeWriter(); //QRCode as a BitMatrix 2D array

            Dictionary <EncodeHintType, object> hint = new Dictionary <EncodeHintType, object>();

            hint.Add(EncodeHintType.MARGIN, Margin); // margin of the QRCode image
            hint.Add(EncodeHintType.ERROR_CORRECTION, Correction);

            var matrix = qr.encode(Text, BarcodeFormat.QR_CODE, ImageSize, ImageSize, hint); // encode QRCode matrix from source text

            ZXing.BarcodeWriter w = new ZXing.BarcodeWriter();
            Bitmap img            = w.Write(matrix);                    // QRCode Bitmap image
            string tempFile       = Path.GetTempFileName();             //create a temp file to save QRCode image

            img.Save(tempFile, System.Drawing.Imaging.ImageFormat.Png); //save QRCode image to temp file


            //old one - use clipboard
            //MemoryStream ms = new MemoryStream();
            //img.Save(ms, System.Drawing.Imaging.ImageFormat.Png); //save QRCode image to memory stream
            //System.Drawing.Image i = System.Drawing.Image.FromStream(ms); // create image in Image form
            //Clipboard.SetDataObject(i);// set image to clipboard



            return(tempFile);
        }