<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      趣味二維碼生成

      背景介紹

      最近在 Github 看到了一個有趣的項目 amazing-qr,它支持生成普通二維碼,帶圖片的藝術二維碼,動態二維碼。

      項目是用 python 編寫的,以命令行的方式運行生成,不太方便調用,因此,我把它封裝成了 Api。

       

      示例展示

       1. 普通二維碼

       

      2. 圖片二維碼

       

      3. 動態二維碼

       

      如何使用

      1. 克隆代碼,https://github.com/ErikXu/qrcode-service.git
      2. 安裝 docker
      3. 執行 bash build.sh 指令編譯程序
      4. 執行 bash pack.sh 指令打包鏡像
      5. 執行 bash run.sh 運行容器
      6. 訪問 http://localhost:5000/swagger/index.html 進行 Api 調用

       

      指令介紹

      1. 說明

      amzqr Words                   # 用來生成二維碼的內容
            [-v {1,2,3,...,40}]     # 二維碼是正方形的,此參數表示二維碼的邊長,范圍 1-40,不指定將基于二維碼內容長度和糾錯等級判斷
            [-l {L,M,Q,H}]          # 糾錯等級,范圍是 L、M、Q、H,從左到右依次升高,默認為 H
            [-n output-filename]    # 輸出二維碼文件名
            [-d output-directory]   # 輸出二維碼文件夾
            [-p picture_file]       # 用于合成二維碼的圖片
            [-c]                    # 是否生成彩色二維碼
            [-con contrast]         # 對比度,表示原始圖片,更小的值表示更低對比度,更大反之,默認值為 1.0
            [-bri brightness]       # 亮度,用法和取值與 -con 相同,默認值為 1.0

       

      2. 示例

      # 生成普通二維碼
      amzqr https://github.com
      
      # 生成普通二維碼,設置邊長為 10, 糾錯等級為 M
      amzqr https://github.com -v 10 -l M
      
      # 生成普通二維碼,設置邊長為 10, 糾錯等級為 M,輸出到 /tmp/qrcode.png
      amzqr https://github.com -v 10 -l M -n qrcode.png -d /tmp
      
      # 生成黑白圖片二維碼,設置邊長為 10, 糾錯等級為 M,輸出到 /tmp/qrcode.png
      amzqr https://github.com -v 10 -l M -n qrcode.png -d /tmp -p github.png
      
      # 生成彩色圖片二維碼,設置邊長為 10, 糾錯等級為 M,輸出到 /tmp/qrcode.png
      amzqr https://github.com -v 10 -l M -n qrcode.png -d /tmp -p github.png -c
      
      # 生成彩色圖片二維碼,設置邊長為 10, 糾錯等級為 M,輸出到 /tmp/qrcode.png,對比度為 1.0,亮度為 1.0
      amzqr https://github.com -v 10 -l M -n qrcode.png -d /tmp -p github.png -c -con 1.0 -bri 1.0
      
      # 生成動態二維碼,設置邊長為 10, 糾錯等級為 M,輸出到 /tmp/qrcode.gif
      amzqr https://github.com -v 10 -l M -n qrcode.gif -d /tmp -p github.gif -c
      
      # 生成動態二維碼,設置邊長為 10, 糾錯等級為 M,輸出到 /tmp/qrcode.gif,對比度為 1.0,亮度為 1.0
      amzqr https://github.com -v 10 -l M -n qrcode.gif -d /tmp -p github.gif -c -con 1.0 -bri 1.0
      

       

      代碼實現

      有了上述指令介紹,Api 只需要根據輸入參數生成對應的指令進行執行即可,以下是指令參數翻譯過來的實體類:

      public class QRCodeForm
      {
          /// <summary>
          /// Content to gen to qrcode
          /// </summary>
          [Required]
          public string? Text { get; set; }
      
          /// <summary>
          /// Length of the qrcode image range 1 to 40
          /// </summary>
          [Range(1, 40)]
          public int? Version { get; set; } = null;
      
          /// <summary>
          /// Error correction level, is one of L, M, Q and H, default H
          /// </summary>
          [DefaultValue("H")]
          [LevelValidation]
          public string Level { get; set; } = "H";
      
          /// <summary>
          /// Is qrcode image colorized
          /// </summary>
          public bool Colorized { get; set; } = false;
      
          /// <summary>
          /// The contrast of the qrcode image, defaule 1.0
          /// </summary>
          [DefaultValue(1.0)]
          public double Contrast { get; set; } = 1.0;
      
          /// <summary>
          /// The brightness of the qrcode image, defaule 1.0
          /// </summary>
          [DefaultValue(1.0)]
          public double Brightness { get; set; } = 1.0;
      } 

       

      根據輸入參數生成指令:

      [HttpPost]
      public async Task<IActionResult> Generate([FromForm] QRCodeForm form, IFormFile? file)
      {
          var outDir = Directory.GetCurrentDirectory();
          var isUnix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
          if (isUnix)
          {
              outDir = "/tmp";
          }
      
          var command = $"amzqr {form.Text} -l {form.Level.ToUpper()}";
      
          var isGif = false;
          var tmpPath = string.Empty;
          if (file != null)
          {
              var ext = Path.GetExtension(file.FileName).ToLower();
              if (ext == ".gif")
              {
                  isGif = true;
              }
      
              tmpPath = Path.Combine(outDir, isGif ? $"{Guid.NewGuid()}.gif" : $"{Guid.NewGuid()}.png");
              await using var stream = System.IO.File.Create(tmpPath);
              await file.CopyToAsync(stream);
      
              command = form.Colorized ? $"{command} -p {tmpPath} -c" : $"{command} -p {tmpPath}";
      
              if (form.Version == null)
              {
                  form.Version = 10;
              }
          }
      
          if (form.Version != null)
          {
              command = $"{command} -v {form.Version}";
          }
      
          var filename = isGif ? $"{Guid.NewGuid()}.gif" : $"{Guid.NewGuid()}.png";
          var filePath = Path.Combine(outDir, filename);
      
          command = $"{command} -n {filePath} -d {outDir} -con {form.Contrast} -bri {form.Brightness}";
      
          var (code, message) = ExecuteCommand(command);
      
          if (code != 0)
          {
              return StatusCode(StatusCodes.Status500InternalServerError, new { Message = message });
          }
      
          var bytes = await System.IO.File.ReadAllBytesAsync(filePath);
          System.IO.File.Delete(filePath);
      
          if (!string.IsNullOrWhiteSpace(tmpPath))
          {
              System.IO.File.Delete(tmpPath);
          }
      
          var contentType = isGif ? "image/gif" : "image/png";
          return File(bytes, contentType, filename);
      }

       

      .Net 執行指令:

      private (int, string) ExecuteCommand(string command)
      {
          var isUnix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
          var escapedArgs = command.Replace("\"", "\\\"");
          var process = new Process
          {
              StartInfo = new ProcessStartInfo
              {
                  FileName = isUnix ? "/bin/sh" : "powershell",
                  Arguments = isUnix ? $"-c \"{escapedArgs}\"" : command,
                  RedirectStandardOutput = true,
                  RedirectStandardError = true,
                  UseShellExecute = false,
                  CreateNoWindow = true
              }
          };
      
          process.Start();
          process.WaitForExit();
      
          var message = process.StandardOutput.ReadToEnd();
          if (process.ExitCode != 0)
          {
              message = process.StandardError.ReadToEnd();
          }
      
          return (process.ExitCode, message);
      }

       

      鏡像分析

      由于使用 amzqr 需要 python 環境,因此,我們需要在鏡像中安裝 python 和 amzqr。這里采用的是 .Net --self-contained 及 SingleFile 的發布模式,基礎鏡像使用 Alpine 即可,這樣鏡像會比較小,最終鏡像信息如下:

      docker images
      REPOSITORY                                            TAG                     IMAGE ID            CREATED             SIZE
      qrcode-service                                        1.0.0                   ed951bd0f183        11 hours ago        579MB
      
      docker history qrcode-service:1.0.0
      IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
      ed951bd0f183        11 hours ago        /bin/sh -c #(nop)  ENTRYPOINT ["/app/QRCodeS…   0B
      5d8233b13569        11 hours ago        /bin/sh -c #(nop)  EXPOSE 5000                  0B
      243defd1dbf8        11 hours ago        /bin/sh -c #(nop) WORKDIR /app                  0B
      35107ba54a38        11 hours ago        /bin/sh -c #(nop) COPY dir:41655fe6f5c1f2696…   89.7MB              # .Net 程序大小
      6397fd089666        11 hours ago        /bin/sh -c pip install amzqr                    163MB               # amzpr 大小
      dd22ff3f30f3        11 hours ago        /bin/sh -c apk add build-base python3-dev       239MB               # gcc + python-dev 大小
      ebfe625d9bbf        11 hours ago        /bin/sh -c pip3 install --no-cache --upgrade…   17.8MB              # setuptools 大小
      27b796e1ee1b        11 hours ago        /bin/sh -c python3 -m ensurepip                 12.8MB              # pip 大小
      897ce778f7ac        11 hours ago        /bin/sh -c apk add --update --no-cache pytho…   44.4MB              # python 大小
      f50f70c2e77e        11 hours ago        /bin/sh -c #(nop)  ENV PYTHONUNBUFFERED=1       0B
      383310ca7431        11 hours ago        /bin/sh -c apk add --no-cache         ca-cer…   4.32MB              # .Net 依賴大小
      b5cadfbc43c4        11 hours ago        /bin/sh -c apk update                           2.16MB              # 升級 apk 源增加的大小
      c594ce5ebfef        11 hours ago        /bin/sh -c sed -i 's/dl-cdn.alpinelinux.org/…   95B
      021b3423115f        9 months ago        /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
      <missing>           9 months ago        /bin/sh -c #(nop) ADD file:34eb5c40aa0002892…   5.6MB               # Alpine 鏡像大小

      .Net 發布壓縮參數 PublishTrimmed=true 在 .Net 6 貌似失效了,不然 .Net 程序的大小應該在 40M 左右。

       

      開發要求

      1. 操作系統

      可以在 Windows,Linux,Mac 上進行開發,比較推薦 Linux,在 Windows 環境下使用圖片合成時會有文件占用的問題。

       

      2. 環境依賴

      python3 以及 amzpr。

       

      項目地址

      https://github.com/ErikXu/qrcode-service

      歡迎大家 star,提 pr,提 issue,在文章或者在公眾號 - 跬步之巔留言交流。

      posted @ 2022-05-11 08:36  編程玩家  閱讀(1093)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 亚洲国产v高清在线观看| 亚洲欧美日韩在线码| 亚洲av无码国产在丝袜线观看| 777奇米四色成人影视色区| 国产成人精品电影在线观看| 久久精品国产99亚洲精品| 99精品热在线在线观看视| 亚洲 欧美 综合 另类 中字| 亚洲欧洲日产国码无码网站| 成人看的污污超级黄网站免费| 邳州市| 早起邻居人妻奶罩太松av| 丰满无码人妻热妇无码区| 少妇无码一区二区三区免费| 老色批国产在线观看精品| 日韩在线成年视频人网站观看| 真实单亲乱l仑对白视频| 久久亚洲精品亚洲人av| 中文字幕av一区二区| 又爽又黄又无遮挡的视频| 在线看免费无码av天堂的| 人妻一区二区三区三区| 天堂俺去俺来也www色官网| 激情综合色综合啪啪开心| 孕妇特级毛片ww无码内射| 无码国产一区二区三区四区| 久久99日本免费国产精品| 人成午夜免费大片| 美女网站免费观看视频| 久久涩综合一区二区三区| 超碰成人人人做人人爽| 国产无套内射普通话对白| 日本大片在线看黄a∨免费| 国产精品国产三级国产专业| 人妻夜夜爽天天爽三区丁香花| 超碰成人人人做人人爽| 久久精品日韩av无码| 爱啪啪精品一区二区三区| 欧美成本人视频免费播放| 久久国产精品不只是精品| 亚洲欧美日韩第一页|