很久沒發文章了,最近登陸看到有朋友評論了golang生成二維碼的文章,想了解下生成個性二維碼的解決方案!git
實現思路 ,網上搜相關資料幾乎沒有, 沒有那就就本身想吧,就去看了下草料二維碼; github
而後忽然就有感受了 不就是把像素的顏色替換嘛 這還不簡單golang
1 打開二維碼圖片
2 打開要填充的圖片
3 將要填充的圖片剪裁成和二維碼同樣大小
4 分析二維碼的每一個像素 替換成圖片的像素就好了ui
如下是生成的例子:spa
package main import ( "fmt" "github.com/nfnt/resize" "image" "image/color" "image/draw" "log" "os" "time" _ "image/jpeg" _ "image/gif" "image/png" ) func main() { // 打開二維碼圖片 qrFile, err := os.Open("img/qr.png") if err != nil { log.Fatalf("打開二維碼失敗 %s", err.Error()) return } defer qrFile.Close() // 將二維碼文件接碼成圖片 img, _, err := image.Decode(qrFile) if err != nil { log.Fatalf("image decode error %s", err.Error()) return } // 獲取二維碼的寬高 width, height := img.Bounds().Max.X, img.Bounds().Max.Y // 打開要填充的圖片 bgFile, err := os.Open("bg/7.jpg") if err != nil { log.Fatalf("打開填充圖失敗 %s", err.Error()) return } defer bgFile.Close() // 將填充圖解碼成png圖片 bgImg, _, err := image.Decode(bgFile) if err != nil { log.Fatalf("填充圖解碼失敗 %s", err.Error()) return } // 獲取填充圖的寬高 bgWidth, bgHeight := bgImg.Bounds().Max.X, bgImg.Bounds().Max.Y // 檢測二維碼和填充圖寬高是否一致 if width != bgWidth || height != bgHeight { // 若是不一致將填充圖剪裁 bgImg = ImageResize(bgImg, width, height) } // 開始填充二維碼 for y := 0; y < img.Bounds().Max.X; y++ { for x := 0; x < img.Bounds().Max.X; x++ { qrImgColor := img.At(x, y) // 檢測圖片顏色 若是rgb值是 255 255 255 255 則像素點爲白色 跳過 // 若是rgba值是 0 0 0 0 則爲透明色 跳過 switch img.(type) { case *image.NRGBA: c := qrImgColor.(color.NRGBA) if (c.R == 0 && c.G == 0 && c.B == 0 && c.A == 0) || (c.R == 255 && c.G == 255 && c.B == 255 && c.A == 255) { continue } case *image.RGBA: c := qrImgColor.(color.RGBA) if (c.R == 0 && c.G == 0 && c.B == 0 && c.A == 0) || (c.R == 255 && c.G == 255 && c.B == 255 && c.A == 255) { continue } } // 獲取要填充的圖片的顏色 bgImgColor := bgImg.At(x, y) // 填充顏色 switch bgImg.(type) { case *image.RGBA64: c := bgImgColor.(color.RGBA64) img.(draw.Image).Set(x, y, color.RGBA64{R: c.R, G: c.G, B: c.B, A: c.A}) case *image.NRGBA: c := bgImgColor.(color.NRGBA) img.(draw.Image).Set(x, y, color.NRGBA{R: c.R, G: c.G, B: c.B, A: c.A}) case *image.RGBA: c := bgImgColor.(color.RGBA) img.(draw.Image).Set(x, y, color.RGBA{R: c.R, G: c.G, B: c.B, A: c.A}) case *image.YCbCr: c := bgImgColor.(color.YCbCr) img.(draw.Image).Set(x, y, color.YCbCr{Y: c.Y, Cb: c.Cb, Cr: c.Cr}) default: fmt.Println("error") } } } filename := fmt.Sprintf("%s.png", time.Now().Format("20060102150405")) // 寫入文件 outFile, err := os.Create(filename) if err != nil { log.Fatal(err) } defer outFile.Close() _ = png.Encode(outFile, img) } func ImageResize(src image.Image, w, h int) image.Image { return resize.Resize(uint(w), uint(h), src, resize.Lanczos3) }
1 儘可能用png的二維碼和填充圖
2 案例中png和jpg gif圖片均可以填充 其餘格式的圖片本身加就好了code