feat(Go-StudyExample):添加两种二维码生成使用示例,添加两种图片压缩方式、添加水印示例,添加文字到图片
This commit is contained in:
@@ -6,20 +6,28 @@
|
||||
|
||||
package main
|
||||
|
||||
import "Go-StudyExample/example"
|
||||
import (
|
||||
"Go-StudyExample/example"
|
||||
)
|
||||
|
||||
func main() {
|
||||
//--------------------------测试mapStructure的功能-----
|
||||
//这边的四种使用方式差别感觉不是很大...
|
||||
example.MapStructureTestFunc()
|
||||
example.MapStructureTestFunc1()
|
||||
example.MapStructureTestFunc2()
|
||||
example.MapStructureTestFunc3()
|
||||
|
||||
//--------------------------测试json包的转换功能
|
||||
example.JsonMarshalTest()
|
||||
example.JsonUnmarshalTest()
|
||||
|
||||
example.TestClone()
|
||||
////--------------------------测试mapStructure的功能-----
|
||||
////这边的四种使用方式差别感觉不是很大...
|
||||
//example.MapStructureTestFunc()
|
||||
//example.MapStructureTestFunc1()
|
||||
//example.MapStructureTestFunc2()
|
||||
//example.MapStructureTestFunc3()
|
||||
//
|
||||
////--------------------------测试json包的转换功能
|
||||
//example.JsonMarshalTest()
|
||||
//example.JsonUnmarshalTest()
|
||||
//
|
||||
////克隆测试
|
||||
//example.TestClone()
|
||||
//
|
||||
////二维码测试
|
||||
//example.QrCodeTest()
|
||||
|
||||
//图片测试
|
||||
example.ImageTest()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2020/7/6 11:06
|
||||
* @Description:
|
||||
*/
|
||||
|
||||
package example
|
||||
|
||||
func assert(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2020/7/6 10:42
|
||||
* @Description:参考地址:https://www.cnblogs.com/dfsxh/articles/11082359.html
|
||||
*/
|
||||
|
||||
package example
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/golang/freetype"
|
||||
"github.com/nfnt/resize"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
filePath = "example/image/image.jpg" //原始logo图片路径
|
||||
logoPath = "example/image/log.png" //原始图片路径
|
||||
|
||||
resizeImagePath = "example/image/resize.png" //重置尺寸图片的路径
|
||||
resizeImagePath2 = "example/image/resize2.png" //重置尺寸图片的路径
|
||||
resizeWidth = 1000 //重置尺寸图片的宽度
|
||||
resizeHeight = 300 //重置尺寸图片的高度
|
||||
|
||||
waterMarkPath = "example/image/waterMakerImage.png" //携带水印的图片
|
||||
wordPath = "example/image/wordPath.png" //携带文字的图片
|
||||
)
|
||||
|
||||
func ImageTest() {
|
||||
|
||||
AddWordToImg() //设置文字到图片
|
||||
|
||||
//图片压缩的两种方式,压缩率好像差不多,对应的尺寸比例不一样
|
||||
ResizeImage()
|
||||
ResizeImage2()
|
||||
|
||||
AddWaterMark() //添加水印
|
||||
}
|
||||
|
||||
//图片压缩
|
||||
func ResizeImage() {
|
||||
// 打开图片并解码
|
||||
fileOrigin, _ := os.Open(filePath)
|
||||
originFile, _ := os.Stat(filePath)
|
||||
origin, err := jpeg.Decode(fileOrigin) //这边这个方法之前尝试使用截图的数据来做,会报错:missing SOI marker,似乎是因为base64编码的问题
|
||||
defer fileOrigin.Close()
|
||||
|
||||
canvas := resize.Resize(resizeWidth, resizeHeight, origin, resize.Lanczos3) //尺寸重置的画布对象
|
||||
fileOut, err := os.Create(resizeImagePath) //创建重置大小后的图片文件
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer fileOut.Close()
|
||||
_ = jpeg.Encode(fileOut, canvas, &jpeg.Options{Quality: 80}) //编码对应的重置后图片文件(Options中的参数代表图片质量)
|
||||
targetFile, _ := os.Stat(resizeImagePath)
|
||||
fmt.Println(fmt.Sprintf("原始图片长度%d,当前图片长度%d", originFile.Size(), targetFile.Size()))
|
||||
}
|
||||
|
||||
//图片压缩2(这种方式似乎会按照图片的比例进行缩放-取较小的长或宽的比例进行缩放,可以尝试调整一下resize的长度来对比结果)
|
||||
func ResizeImage2() {
|
||||
// 打开图片并解码
|
||||
fileOrigin, _ := os.Open(filePath)
|
||||
originFile, _ := os.Stat(filePath)
|
||||
origin, err := jpeg.Decode(fileOrigin) //这边这个方法之前尝试使用截图的数据来做,会报错:missing SOI marker,似乎是因为base64编码的问题
|
||||
defer fileOrigin.Close()
|
||||
|
||||
canvas := resize.Thumbnail(resizeWidth, resizeHeight, origin, resize.Lanczos3) //尺寸重置的画布对象
|
||||
fileOut, err := os.Create(resizeImagePath2) //创建重置大小后的图片文件
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer fileOut.Close()
|
||||
_ = jpeg.Encode(fileOut, canvas, &jpeg.Options{Quality: 100}) //编码对应的重置后图片文件(Options中的参数代表图片质量)
|
||||
targetFile, _ := os.Stat(resizeImagePath2)
|
||||
fmt.Println(fmt.Sprintf("原始图片长度%d,当前图片长度%d", originFile.Size(), targetFile.Size()))
|
||||
}
|
||||
|
||||
//在图片上添加水印
|
||||
func AddWaterMark() {
|
||||
// 打开图片并解码
|
||||
fileOrigin, _ := os.Open(filePath)
|
||||
origin, _ := jpeg.Decode(fileOrigin)
|
||||
defer fileOrigin.Close()
|
||||
|
||||
// 打开水印图并解码
|
||||
fileWatermark, _ := os.Open(logoPath)
|
||||
watermark, _ := png.Decode(fileWatermark)
|
||||
defer fileWatermark.Close()
|
||||
originSize := origin.Bounds() //原始图界限
|
||||
|
||||
canvas := image.NewNRGBA(originSize) //创建新图层
|
||||
|
||||
draw.Draw(canvas, originSize, origin, image.ZP, draw.Src) // 贴原始图
|
||||
|
||||
draw.Draw(canvas, watermark.Bounds().Add(image.Pt(originSize.Dx()/2, originSize.Dy()/2)), watermark, image.ZP, draw.Over) // 贴水印图
|
||||
|
||||
//生成新图片
|
||||
createImage, _ := os.Create(waterMarkPath)
|
||||
_ = jpeg.Encode(createImage, canvas, &jpeg.Options{95})
|
||||
defer createImage.Close()
|
||||
}
|
||||
|
||||
type RGBA struct { // Pix保管图像的像素色彩信息,顺序为R, G, B, A
|
||||
// 像素(x, y)起始位置是Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4]
|
||||
Pix []uint8
|
||||
// Stride是Pix中每行像素占用的字节数
|
||||
Stride int
|
||||
// Rect是图像的范围
|
||||
Rect image.Rectangle
|
||||
}
|
||||
|
||||
const (
|
||||
fontPath = "F://Go_BySelf//src//Go-StudyExample//example//image//微软vista黑体.ttf" //字体的存储位置
|
||||
content = "i love 许小baby"
|
||||
)
|
||||
|
||||
//在图片上添加文字
|
||||
//使用到的包:go get github.com/golang/freetype
|
||||
//参考地址;http://www.sunaloe.cn/d/36.html
|
||||
func AddWordToImg() {
|
||||
img := copyBackgroundImage() //从图片中复制出图层
|
||||
generateContentFont(img) //设置字体和Content
|
||||
createImage, _ := os.Create(wordPath)
|
||||
_ = jpeg.Encode(createImage, img, &jpeg.Options{Quality: 95})
|
||||
defer createImage.Close()
|
||||
}
|
||||
|
||||
func generateContentFont(img *image.NRGBA) {
|
||||
//读取字体数据
|
||||
fontBytes, err := ioutil.ReadFile(fontPath)
|
||||
checkErr(err)
|
||||
|
||||
//载入字体数据
|
||||
font, err := freetype.ParseFont(fontBytes)
|
||||
checkErr(err)
|
||||
|
||||
f := freetype.NewContext()
|
||||
//设置分辨率
|
||||
f.SetDPI(72)
|
||||
//设置字体
|
||||
f.SetFont(font)
|
||||
//设置尺寸
|
||||
f.SetFontSize(100)
|
||||
f.SetClip(img.Bounds())
|
||||
//设置输出的图片
|
||||
f.SetDst(img)
|
||||
//设置字体颜色
|
||||
f.SetSrc(image.NewUniform(color.RGBA{R: 12, G: 225, B: 12, A: 99}))
|
||||
|
||||
//设置字体的位置
|
||||
pt := freetype.Pt(500, 500+int(f.PointToFixed(26))>>8)
|
||||
|
||||
_, err = f.DrawString(content, pt)
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
func copyBackgroundImage() *image.NRGBA {
|
||||
imgFile, _ := os.Open(filePath)
|
||||
defer imgFile.Close()
|
||||
//获取到底部的照片作为背景,也可以理解为是在底部的照片上面写入文字
|
||||
backGround, _, _ := image.Decode(imgFile)
|
||||
dx := backGround.Bounds().Size().X
|
||||
dy := backGround.Bounds().Size().Y
|
||||
|
||||
img := image.NewNRGBA(image.Rect(0, 0, dx, dy)) //初始化新生成图片
|
||||
|
||||
//通过循环像素点把图片复制到新的图层.作为新图层的背景,这边其实也可以直接设置非图片的背景图
|
||||
for y := 0; y < dy; y++ {
|
||||
for x := 0; x < dx; x++ {
|
||||
img.Set(x, y, backGround.At(x, y))
|
||||
}
|
||||
}
|
||||
|
||||
return img
|
||||
}
|
||||
|
||||
func checkErr(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* @Author : huangzj
|
||||
* @Time : 2020/7/3 12:00
|
||||
* @Description:参考文章:https://zhuanlan.zhihu.com/p/32035735
|
||||
*/
|
||||
|
||||
package example
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/boombuler/barcode"
|
||||
"github.com/boombuler/barcode/qr"
|
||||
qrCode "github.com/skip2/go-qrcode"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
url1 = "https://image.baidu.com/search/detail?ct=503316480&z=undefined&tn=baiduimagedetail&ipn=d&word=%E7%BE%8E%E5%A5%B3%E5%9B%BE%E7%89%87&step_word=&ie=utf-8&in=&cl=2&lm=-1&st=undefined&hd=undefined&latest=undefined©right=undefined&cs=1848592761,1307412614&os=1322849054,135797925&simid=0,0&pn=644&rn=1&di=41830&ln=2454&fr=&fmq=1593763755230_R&fm=&ic=undefined&s=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&is=0,0&istype=0&ist=&jit=&bdtype=11&spn=0&pi=0&gsm=258&hs=2&objurl=http%3A%2F%2Fup.enterdesk.com%2Fedpic%2Fb2%2F9d%2Fac%2Fb29dacffee2403e8b3bec67c9abcd647.jpg&rpstart=0&rpnum=0&adpicid=0&force=undefined"
|
||||
url2 = "https://www.baidu.com/link?url=oH5FRzYYHiZNm84fp0CaQtGZgw2-WRZgIj7B3Mmmzy0iM_EcVHkHmSHQwU6LuPBi6o24N2ObdLJEL1l6aIY5KeXia3S-9ysVL5K7Qe_SnHeXNOxqbI3UbpSBktjFfbIunH9Y9OteFNO-YYsx2Nh1YbOVrZhzh0Ne26W3_73xgsX7ys418xQJOGiGteVwk6UaEqPaQgqlUtSHBCSjH_FZuJmxswzP-5X5Hg894diQSm8136aulR3oC7AB0LFSmCZoIviAdOGagItOAqIdTP_P7NWn7rzebKAFoS0j-q8fMLvoZJYK1xTir1-scoBZ1aTSdEsrhTcpKzhHyG5CarDTj3BdmD96JzBppy9rDMXQ8XstX8gzJb4LrTCdg5t9RMK11wzjmgJhkj-9deb7iZqsdVDBgUpur-UxR6vsa5OvXkgLd4Tzv1fTm3-UjdYgfPDUQ9pGGLzLQQKO8i4eEEFsrSJZCx4eAdD94GBbOOVpDZtwJSwVqLJKvPtu8h0gt-lOmktaHxJffIXZfBKtfMfCnc_fqomMQAGoaaIkehD9X57zeK6OZg1f3kM7Azv5pzs2ITgaErADeN0vdQbZ8fWBT0tqTmmDNRJLgzVnBx9V9FMhgD6eAOHunHxHAT5g_DMr&timg=https%3A%2F%2Fss0.bdstatic.com%2F94oJfD_bAAcT8t7mm9GUKT-xh_%2Ftimg%3Fimage%26quality%3D100%26size%3Db4000_4000%26sec%3D1593763752%26di%3D3a1f64455c44b927fc36a894140e279e%26src%3Dhttp%3A%2F%2F00.minipic.eastday.com%2F20170420%2F20170420105628_ea6da92abc46098d8e03ad2ee55abeb7_9.jpeg&click_t=1593763828401&s_info=2543_1335&wd=&eqid=916eb61300000776000000065efee7a7"
|
||||
url3 = "http://note.youdao.com/noteshare?id=de3af43fd227f9a23e23f50d0dab105f"
|
||||
|
||||
qrcode1 = "example/image/log_qrcode.png"
|
||||
qrcode2 = "example/image/log_qrcode1.png"
|
||||
)
|
||||
|
||||
func QrCodeTest() {
|
||||
|
||||
fmt.Printf("通过github.com/skips/go-qrcode 实现生成二维码")
|
||||
|
||||
//生成黑白二维码
|
||||
err := qrCode.WriteFile(url1, qrCode.High, 255, qrcode1)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//生成字节数组信息
|
||||
qrBytes, err := qrCode.Encode(url3, qrCode.High, 255)
|
||||
for _, r := range qrBytes {
|
||||
fmt.Println(r)
|
||||
}
|
||||
|
||||
//自定义二维码信息
|
||||
qrCode1, err := qrCode.New(url2, qrCode.Medium)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
qrCode1.BackgroundColor = color.RGBA{250, 250, 50, 255} //设置背景色
|
||||
qrCode1.ForegroundColor = color.Black //设置二维码内背景色
|
||||
qrCode1.WriteFile(256, qrcode2)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
fmt.Printf("通过 github.com/boombuler/barcode 实现生成二维码")
|
||||
content := "https://zhuanlan.zhihu.com/p/59125443" //二维码内容信息
|
||||
|
||||
code, err2 := qr.Encode(content, qr.L, qr.Unicode) //对二维码进行编码
|
||||
assert(err2)
|
||||
|
||||
img, err3 := barcode.Scale(code, 300, 300) //图片大小设置
|
||||
assert(err3)
|
||||
|
||||
file, err4 := os.Create("F:/Go_BySelf/src/Go-StudyExample/example/image/qr_code.png") //创建文件
|
||||
assert(err4)
|
||||
|
||||
err5 := png.Encode(file, img) //图片编码生成
|
||||
//err6 := jpeg.Encode(file, img, &jpeg.Options{100}) //图像质量值为100,是最好的图像显示
|
||||
assert(err5)
|
||||
|
||||
err6 := file.Close()
|
||||
assert(err6)
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 409 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
Binary file not shown.
@@ -2,4 +2,18 @@ module Go-StudyExample
|
||||
|
||||
go 1.13
|
||||
|
||||
require github.com/goinggo/mapstructure v0.0.0-20140717182941-194205d9b4a9
|
||||
require (
|
||||
github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75 // indirect
|
||||
github.com/boombuler/barcode v1.0.0
|
||||
github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 // indirect
|
||||
github.com/goinggo/mapstructure v0.0.0-20140717182941-194205d9b4a9
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/kardianos/govendor v1.0.9 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519 // indirect
|
||||
golang.org/x/tools v0.0.0-20200708003708-134513de8882 // indirect
|
||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||
)
|
||||
|
||||
@@ -6,3 +6,18 @@ json与struct之间转换处理工具使用示例
|
||||
|
||||
|
||||
2020/5/15 : 添加CloneExample,测试go语言的对象内存和深度克隆的实现关于对象克隆可参考文章[知乎-](https://zhuanlan.zhihu.com/p/59125443)、[知乎-](https://zhuanlan.zhihu.com/p/58065429)
|
||||
|
||||
|
||||
2020/7/8 : 添加两种二维码生成使用示例,添加两种图片压缩方式、添加水印示例,添加文字到图片
|
||||
|
||||
|
||||
# mod vendor模式加载包
|
||||
通过go mod的方式加载的github上面的包会有报红的问题,但是包本身是可以运行的,这样就是会有一个问题,如果你想要点击去看方法的内容,没办法做到
|
||||
|
||||
查阅了网上提供的处理方式,通过设置GOPATH 和Go Modules(vgo)可以解决相应的问题,但是我在这样处理之后依然会出现报红的问题
|
||||
|
||||
后面通过使用vendor包的方式来处理,就避免了报红的问题
|
||||
|
||||
处理步骤如下 :
|
||||
- 通过 go get github.com/kardianos/govendor 命令下载govendor命令
|
||||
- 通过 go mod vendor 切换到vendor管理
|
||||
|
||||
Reference in New Issue
Block a user