Golang Gin Practice Series 15 generate two-dimensional code, merge poster

Source: Internet
Author: User

Golang Gin Practice Series 15 generate two-dimensional code, merge poster

Original address: Golang Gin Practice Series 15 generate two-dimensional code, merge poster
Project Address: Https://github.com/EDDYCJY/go ...

If it helps, you're welcome to a Star.

Objective

In this section, you will implement the following functional fine-grained items:

1, generate two-dimensional code

2. Combined poster (background map + QR code)

Realize

First, you need to add the two-D code and the storage path of the poster to the APP configuration item, and we agree that the configuration item name is a QrCodeSavePath value ofqrcode/

After multiple sections you should be able to complete, if you do not understand can refer to Go-gin-example

Generate two-dimensional code

Installation

$ go get -u github.com/boombuler/barcode

Tool Pack

Consider the creation of a QR code this action is the definition of the toolkit, and there is a common possibility to create a new Pkg/qrcode/qrcode.go file, write content:

Package Qrcodeimport ("Image/jpeg" "Github.com/boombuler/barcode" "Github.com/boombuler/barcode/qr" "GITHUB.C Om/eddycjy/go-gin-example/pkg/file "" Github.com/eddycjy/go-gin-example/pkg/setting "" github.com/EDDYCJY/ Go-gin-example/pkg/util ") type QRCode struct {URL string Width int Height int EXT string level QR.E Rrorcorrectionlevel Mode qr. Encoding}const (ext_jpg = ". JPG") func newqrcode (URL string, width, height int, level QR). Errorcorrectionlevel, mode QR.  Encoding) *qrcode {return &qrcode{url:url, Width:width, height:height, Level: Level, Mode:mode, ext:ext_jpg,}}func getqrcodepath () string {return setting. Appsetting.qrcodesavepath}func Getqrcodefullpath () string {return setting. Appsetting.runtimerootpath + setting. Appsetting.qrcodesavepath}func Getqrcodefullurl (name string) string {return setting. Appsetting.prefixurl + "/" + Getqrcodepath () + Name}func GetQrcodefilename (value String) string {return util.     EncodeMD5 (value)}func (q *qrcode) Getqrcodeext () string {return Q.ext}func (q *qrcode) checkencode (path string) bool { SRC: = path + getqrcodefilename (q.url) + q.getqrcodeext () if file.  Checknotexist (src) = = true {return false} return True}func (q *qrcode) Encode (Path string) (string, String, Error) {Name: = Getqrcodefilename (Q.url) + q.getqrcodeext () src: = path + name if file. Checknotexist (src) = = True {code, ERR: = Qr. Encode (Q.url, Q.level, q.mode) if err! = Nil {return "", "", Err} code, err = barcode. Scale (code, q.width, q.height) if err! = Nil {return "", "", err} F, err: = file. Mustopen (name, path) if err! = Nil {return "", "", Err} defer f.close () Err = JPE G.encode (f, Code, nil) if err! = Nil {return "", "", Err}} return name, path, nil}

Here are the main focus func (q *QrCode) Encode methods, do the following things:

    • Get the QR code generation path
    • Create two-dimensional code
    • Zoom the QR code to the specified size
    • New file to store QR code image
    • Writes the image (QR code) to a file in the JPEG 4:2:0 baseline format

In addition jpeg.Encode(f, code, nil) , the third parameter sets its image quality, with a default value of 75

// DefaultQuality is the default quality encoding parameter.const DefaultQuality = 75// Options are the encoding parameters.// Quality ranges from 1 to 100 inclusive, higher is better.type Options struct {    Quality int}

Routing Methods

1, the first step

New Generatearticleposter method for interface development in Routers/api/v1/article.go

2, the second step

New routes in Routers/router.go's Apiv1 apiv1.POST("/articles/poster/generate", v1.GenerateArticlePoster)

3, the third step

Modify the Generatearticleposter method and write the corresponding build logic as follows:

const (    QRCODE_URL = "https://github.com/EDDYCJY/blog#gin%E7%B3%BB%E5%88%97%E7%9B%AE%E5%BD%95")func GenerateArticlePoster(c *gin.Context) {    appG := app.Gin{c}    qrc := qrcode.NewQrCode(QRCODE_URL, 300, 300, qr.M, qr.Auto)    path := qrcode.GetQrCodeFullPath()    _, _, err := qrc.Encode(path)    if err != nil {        appG.Response(http.StatusOK, e.ERROR, nil)        return    }    appG.Response(http.StatusOK, e.SUCCESS, nil)}

Verify

Access via POST method http://127.0.0.1:8000/api/v1/articles/poster/generate?token=$token (note $token)

Determine if the function is normal by checking two points, as follows:

1. Whether the result of access is 200

2. Whether the local directory successfully generated two-dimensional code image

Merge poster

In this section, the implementation of the two-dimensional code image and background map into a new picture, can be used for common promotional posters and other business scenarios

Background map

Save the background map as runtime/qrcode/bg.jpg (actual application, can exist in OSS or elsewhere)

Service method

Open the Service/article_service directory, create a new Article_poster.go file, and write the contents:

Package Article_serviceimport ("image" "Image/draw" "Image/jpeg" "OS" "github.com/eddycjy/go-gin-example/p    Kg/file "" Github.com/eddycjy/go-gin-example/pkg/qrcode ") type Articleposter struct {postername string *article Qr *qrcode. Qrcode}func Newarticleposter (Postername string, article *article, QR *qrcode. QRCode) *articleposter {return &articleposter{postername:postername, article:article, Q  R:QR,}}func Getposterflag () string {return ' poster '}func (a *articleposter) checkmergedimage (path string) BOOL {if file. Checknotexist (path+a.postername) = = true {return false} return True}func (a *articleposter) openmergedimage (Path String) (*os. File, error) {f, err: = file.     Mustopen (a.postername, path) if err! = Nil {return nil, err} return F, Nil}type articleposterbg struct { Name string *articleposter *rect *pt}type Rect struct {Name string X0 int Y0 int   X1 int Y1 int}type Pt struct {X int Y int}func NEWARTICLEPOSTERBG (name string, AP *articleposter, Rect *r        ECT, PT *pt) *ARTICLEPOSTERBG {return &articleposterbg{name:name, Articleposter:ap, Rect:rect, Pt:pt,}}func (a *ARTICLEPOSTERBG) Generate (String, string, error) {F Ullpath: = QRCode. Getqrcodefullpath () fileName, path, err: = A.qr.encode (FullPath) if err! = Nil {return "", "", err} I F!a.checkmergedimage (path) {MERGEDF, err: = A.openmergedimage (path) if err! = Nil {return "", "", Err} defer mergedf.close () BgF, err: = file. Mustopen (a.name, path) if err! = Nil {return "", "", Err} defer bgf.close () QRF, ERR: = file. Mustopen (fileName, path) if err! = Nil {return "", "", Err} defer qrf.close () BgI Mage, err: = JPEG. Decode (BgF) if err! = Nil {return ' "," ", err} qrimage, err: = JPEG. Decode (QRF) if err! = Nil {return "", "", err} jpg: = image. Newrgba (image. Rect (a.rect.x0, A.rect.y0, a.rect.x1, a.rect.y1)) draw. Draw (jpg, jpg. Bounds (), Bgimage, Bgimage.bounds (). Min, Draw. Over) draw. Draw (jpg, jpg. Bounds (), Qrimage, Qrimage.bounds (). Min.sub (image. Pt (A.pt.x, A.pt.y)), draw. OVER) JPEG. Encode (MERGEDF, JPG, nil)} return fileName, path, nil}

Here func (a *ArticlePosterBg) Generate() 's how to focus on the method and do the following:

    • Get the QR Code storage path
    • Generate two-dimensional code images
    • Check if the merged image (referring to the post-merge poster) exists
    • If it does not exist, the image to be merged is generated MERGEDF
    • Open a pre-stored background map BgF
    • Open the generated QR code image QRF
    • Decodes BgF and QRF returns an image. Image
    • Create a new RGBA image
    • Drawing a background map on an RGBA image (BgF)
    • Draws a two-dimensional code image (QRF) on the specified point on an RGBA image that has a background map drawn
    • Writes a well-drawn RGBA image to the merged image file (MERGEDF) in the JPEG 4:2:0 baseline format

Error code

New error code, error message

Routing Methods

Open the Routers/api/v1/article.go file, modify the Generatearticleposter method, write the final business logic (including the generated QR code and the merged poster), as follows:

Const (Qrcode_url = "https://github.com/EDDYCJY/blog#gin%E7%B3%BB%E5%88%97%E7%9B%AE%E5%BD%95") func Generatearticleposter (c *gin. Context) {appg: = App. GIN{C} article: = &article_service. article{} QR: = QRCode. Newqrcode (Qrcode_url, +, QR. M, QR. Auto)//Currently write dead Gin series path, can increase the business logic postername: = Article_service. Getposterflag () + "-" + qrcode. Getqrcodefilename (QR. URL) + QR. Getqrcodeext () Articleposter: = Article_service. Newarticleposter (Postername, article, QR) Articleposterbgservice: = Article_service. NEWARTICLEPOSTERBG ("Bg.jpg", Articleposter, &article_service. rect{x0:0, y0:0, x1:550, y1:700,}, &article_service. pt{x:125, y:298,},) _, FilePath, err: = Articleposterbgservice.generate () If ER R! = Nil {appg.response (http. Statusok, E.error_gen_article_poster_fail, nil) return} appg.response (http. Statusok, E.SUCCESS, map[string]string{"Poster_url": QRCode. Getqrcodefullurl (Postername), "Poster_save_url": FilePath + Postername,})}

This piece involves a lot of knowledge and is strongly recommended to read below, as follows:

    • Image. Rect
    • Image. Pt
    • Image. Newrgba
    • Jpeg. Encode
    • Jpeg. Decode
    • Draw. Op
    • Draw. Draw
    • Go-imagedraw-package

The libraries involved and associated are recommended to study

Staticfs

In the Routers/router.go file, add the following code:

r.StaticFS("/qrcode", http.Dir(qrcode.GetQrCodeFullPath()))

Verify

Access the full URL path, return the composite poster and sweep the QR code success is correct

Summarize

Two very common business functions are implemented in this section, namely the generation of QR codes and merged posters. I hope you can read the link I gave, this piece of knowledge, want to use good image processing function, must understand the corresponding ideas, extrapolate

Finally, I hope to help you.

Reference

Sample code for this series

    • Go-gin-example
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.