当前位置: 首页 > 后端技术 > PHP

GolangGin练习,连载15,生成二维码,合并海报

时间:2023-03-29 20:15:50 PHP

鍘熸枃鍦板潃锛欸olangGin缁冧範杩炶浇15鐢熸垚浜岀淮鐮佸悎骞舵捣鎶ラ」鐩湴鍧€锛歨ttps://github.com/EDDYCJY/go...濡傛灉瀵逛綘鏈夊府鍔╄鐐逛釜鏄燄煈嶅墠瑷€鏈珷鍐呭锛屽涓嬪姛鑳界粏鑺傚疄鐜帮細1.鐢熸垚浜岀淮鐮?.鍚堝苟娴锋姤锛堣儗鏅浘+浜岀淮鐮侊級瀹炵幇棣栧厛闇€瑕佸湪App閰嶇疆椤逛腑娣诲姞浜岀淮鐮佸強鍏舵捣鎶ョ殑瀛樻斁璺緞銆傛垜浠害瀹氶厤缃」鍚嶇О涓篞rCodeSavePath锛屽€间负qrcode/澶氭搴忓垪鍖栧悗搴旇鍙互瀹屾垚锛屼笉鏄庣櫧鍙互鍙傝€僩o-gin-example鐢熸垚浜岀淮鐮佸苟瀹夎$goget-ugithub.com/boombuler/barcodetoolkit鏉ヨ€冭檻鐢熸垚浜岀淮鐮佺殑鍔ㄤ綔绗﹀悎宸ュ叿鍖呯殑瀹氫箟锛屽叿鏈夊叕寮€浣跨敤鐨勫彲鑳芥€с€傛柊寤簆kg/qrcode/qrcode.go鏂囦欢锛屽啓鍏ュ唴瀹癸細packageqrcodeimport("image/jpeg""github.com/boombuler/barcode""github.com/boombuler/barcode/qr""github.com/EDDYCJY/go-gin-example/pkg/file""github.com/EDDYCJY/go-gin-example/pkg/setting""github.com/EDDYCJY/go-gin-example/pkg/util")typeQrCodestruct{URLstringWidthintHeightintExtstringLevelqr.ErrorCorrectionLevel妯″紡qr.Encoding}const(EXT_JPG=".jpg")funcNewQrCode(urlstring,width,heightint,levelqr.ErrorCorrectionLevel,modeqr.Encoding)*QrCode{return&QrCode{缃戝潃锛歶rl锛屽搴︼細width锛岄珮搴︼細he鍙筹紝绾у埆锛氱骇鍒紝妯″紡锛氭ā寮忥紝鎵╁睍鍚嶏細EXT_JPG锛寎}funcGetQrCodePath锛堬級瀛楃涓瞷杩斿洖璁剧疆.AppSetting.QrCodeSavePath}funcGetQrCodeFullPath锛堬級瀛楃涓瞷杩斿洖璁剧疆.AppSetting.RuntimeRootPath+setting.AppSetting.QrCodeSavePath}funcGetQrCodeFullUrl锛堝悕绉板瓧绗︿覆锛夊瓧绗︿覆{returnsetting.AppSetting.PrefixUrl+"/"+GetQrCodePath()+name}funcGetQrCodeFileName(valuestring)string{returnutil.EncodeMD5(value)}func(q*QrCode)GetQrCodeExt()string{杩斿洖q.Ext}func(q*QrCode)CheckEncode(pathstring)bool{src:=path+GetQrCodeFileName(q.URL)+q.GetQrCodeExt()iffile.CheckNotExist(src)==true{returnfalse}returntrue}func(q*QrCode)Encode(pathstring)(string,string,error){name:=GetQrCodeFileName(q.URL)+q.GetQrCodeExt()src:=path+nameiffile.CheckNotExist(src)=澶嶅埗浠g爜=true{code,err:=qr.Encode(q.URL,q.Level,q.Mode)濡傛灉閿欒!=nil{return"","",err}code,err=barcode.Scale(code,q.Width,q.Height)iferr!=nil{return"","",err}f,err:=鏂囦欢銆侻ustOpen(name,path)iferr!=nil{return"","",err}deferf.Close()err=jpeg.Encode(f,code,nil)iferr!=nil{杩斿洖"","",err}}returnname,path,nil}杩欓噷閲嶇偣鏄痜unc(q*QrCode)Encode鏂规硶锛屽仛浜嗕互涓嬩簨鎯咃細鑾峰彇浜岀淮鐮佺敓鎴愯矾寰勶紝鍒涘缓浜岀淮鐮侊紝缂╂斁浜岀淮鐮佸埌鎸囧畾澶у皬锛屾柊寤轰竴涓瓨鏀句簩缁寸爜鐨勪唬鐮佸浘鐗囨枃浠讹紝灏嗗浘鐗囷紙浜岀淮鐮侊級浠PEG4:2:0鍩虹嚎鏍煎紡鍐欏叆鏂囦欢鍙﹀锛屽湪jpeg.Encode(f,code,nil)锛岀涓変釜鍙傛暟鍙互璁剧疆瀹冪殑鍥惧儚璐ㄩ噺锛岄粯璁ゅ€间负75//DefaultQuality鏄粯璁ょ殑璐ㄩ噺缂栫爜鍙傛暟銆俢onstDefaultQuality=75//Options鏄紪鐮佸弬鏁般€?/璐ㄩ噺鑼冨洿浠?鍒?00锛岃秺楂樿秺濂絙etter.typeOptionsstruct{Qualityint}璺敱鏂规硶1銆佺涓€姝ョ涓€姝ュ湪routers/api/v1/article.go涓坊鍔燝enerateArticlePoster鏂规硶杩涜鎺ュ彛寮€鍙?.绗簩姝ユ坊鍔燼piv1.POST("/鏂囩珷s/娴锋姤/鐢熸垚鈥濓紝v1.浜х敓ArticlePoster)璺敱3.绗笁姝ワ紝淇敼GenerateArticlePoster鏂规硶锛岀紪鍐欑浉搴旂殑鐢熸垚閫昏緫锛屽涓嬶細const(QRCODE_URL="https://github.com/EDDYCJY/blog#gin%E7%B3%BB%E5%88%97%E7%9B%AE%E5%BD%95")funcGenerateArticlePoster(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)iferr!=nil{appG.Response(http.StatusOK,e.ERROR,nil)杩斿洖}appG.Response(http.StatusOK,e.SUCCESS,nil)}閫氳繃妫€鏌ラ獙璇佸http://127.0.0.1:8000/api/v1/articles/poster/generate?token=$token锛堟敞鎰?token锛夌殑璁块棶浜岀偣鍑荤‘璁ゅ姛鑳芥槸鍚︽甯革紝濡備笅锛?.璁块棶缁撴灉鏄惁涓?002锛屾湰鍦扮洰褰曟槸鍚︽垚鍔熺敓鎴愪簩缁寸爜鍥剧墖鍚堝苟娴锋姤鍦ㄨ繖涓€娈碉紝浜岀淮鐮佸浘鐗囧拰鑳屾櫙鍥剧墖浼氳鍚堝苟鎴愪竴涓柊鐨勫浘鐗囷紝鍙敤浜庝笟鍔″満鏅殑鑳屾櫙鍥剧墖姣斿甯歌鐨勫浼犳捣鎶ャ€傚皢鑳屾櫙鍥剧墖淇濆瓨涓簉untime/qrcode/bg.jpg锛堝疄闄呭簲鐢ㄥ彲浠ュ瓨鏀惧湪OSS鎴栧叾浠栧湴鏂癸級銆俿ervice鏂规硶鎵撳紑service/article_service鐩綍锛屾柊寤篴rticle_poster.go鏂囦欢锛屽啓鍏ュ唴瀹癸細packagearticle_serviceimport("image""image/draw""image/jpeg""os""github.com/EDDYCJY/go-gin-example/pkg/file""github.com/EDDYCJY/go-gin-example/pkg/qrcode")typeArticlePosterstruct{PosterNamestring*ArticleQr*qrcode.QrCode}funcNewArticlePoster(posterNamestring,article,qr*qrcode.QrCode)*ArticlePoster{return&ArticlePoster{娴锋姤鍚嶇О:posterName,鏂囩珷:鏂囩珷,Qr:qr,}}funcGetPosterFlag()string{return"poster"}func(a*ArticlePoster)CheckMergedImage(pathstring)bool{iffile.CheckNotExist(path+a.PosterName)==true{returnfalse}returntrue}func(a*ArticlePoster)OpenMergedImage(pathstring)(*os.File,error){f,err:=file.MustOpen(a.PosterName,path)iferr!=nil{杩斿洖nil,err}returnf,nil}typeArticlePosterBgstruct{鍚嶇О瀛楃涓?ArticlePoster*Rect*Pt}typeRectstruct{鍚嶇О瀛楃涓瞂0intY0intX1intY1int}typePtstruct{XintYint}funcNewArticlePosterBg(namestring,ap*鏂囩珷娴锋姤锛宺ect*Rect,pt*Pt)*ArticlePosterBg{return&ArticlePosterBg{Name:name,ArticlePoster:ap,Rect:rect,Pt:pt,}}func(a*ArticlePosterBg)Generate()(string,string,error){瀹屾暣璺緞:=qrcode.GetQrCodeFullPath()鏂囦欢鍚嶃€佽矾寰勩€侀敊璇?=a.Qr.Encode(fullPath)iferr!=nil{return"","",err}if!a.CheckMergedImage(path){mergedF,err:=a.OpenMergedImage(path)iferr!=nil{return"","",err}defermergedF.Close()bgF,err:=file.MustOpen(a.Name,path)iferr!=nil{杩斿洖"","",err}deferbgF.Close()qrF,err:=file.MustOpen(fileName,path)濡傛灉閿欒锛?nil{return"","",err}deferqrF.Close()bgImage,err:=jpeg.Decode(bgF)濡傛灉err!=nil{return"","",err}qrImage,err:=jpeg.瑙g爜(qrF)iferr!=nil{return"","",err}jpg:=image.NewRGBA(image.Rect(a.Rect.X0,a.Rect.Y0,a.Rect.X1,a.鐭╁舰.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)}returnfileName,path,nil}鍏虫敞func(a*ArticlePosterBg)Generate()鏂规硶锛屽仛濡備笅浜嬫儏锛氳幏鍙栦簩缁寸爜瀛樺偍璺緞锛岀敓鎴愪簩缁寸爜鍥剧墖妫€鏌ュ悎骞跺悗鐨勫浘鐗囷紙鎸囧瓨鍌ㄥ悎骞跺悗鐨勬捣鎶ワ級鏄惁瀛樺湪锛屽鏋滀笉瀛樺湪锛屽垯鐢熸垚闇€瑕佸悎骞剁殑鍥剧墖mergedF鎵撳紑涔嬪墠瀛樺偍鐨勮儗鏅浘鐗嘼gF鎵撳紑鐢熸垚鐨勪簩缁寸爜鍥剧墖qrF瑙g爜bgF鍜宷rF杩斿洖image.Image鍒涘缓鏂扮殑RGBA鍥剧墖鍦≧GBA鍥剧墖(bgF)涓婄粯鍒惰儗鏅浘鐗囧湪宸茬粡缁樺埗鑳屾櫙鐨凴GBA鍥剧墖涓奿mage锛屽湪鎸囧畾鐨凱oint涓婄粯鍒朵簩缁寸爜鍥惧儚锛坬rF锛夊苟灏嗙粯鍒剁殑RGBA鍥惧儚鍐欏叆鍚堝苟鍚庣殑iJPEG4:2:0鍩虹嚎鏍煎紡鐨刴age鏂囦欢(mergedF)銆俽outers/api/v1/article.go鏂囦欢锛屼慨鏀笹enerateArticlePoster鏂规硶锛岀紪鍐欐渶缁堢殑涓氬姟閫昏緫锛堝寘鎷敓鎴愪簩缁寸爜鍜屽悎骞舵捣鎶ワ級锛屽涓嬶細const(QRCODE_URL="https://github.com/EDDYCJY/鍗氬#gin%E7%B3%BB%E5%88%97%E7%9B%AE%E5%BD%95")funcGenerateArticlePoster(c*gin.Context){appG:=app.Gin{c}article:=&article_service.Article{}qr:=qrcode.NewQrCode(QRCODE_URL,300,300,qr.M,qr.Auto)//鐩爣鍓嶅啓姝籫in绯诲垪璺緞锛屽彲鑷澧炲姞涓氬姟鍙戝竷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,},)_,鏂囦欢璺緞,閿欒锛?articlePosterBgService.Generate()iferr!=nil{appG.Response(http.StatusOK,e.ERROR_GEN_ARTICLE_POSTER_FAIL,nil)杩斿洖}appG.Response(http.StatusOK,e.SUCCESS,map[string]string{"poster_url":qrcode.GetQrCodeFullUrl(posterName),"poster_save_url":filePath+posterName,})}杩欏潡娑夊強鐨勭煡璇嗘瘮杈冨锛屽己鐑堟帹鑽愰槄璇诲涓嬶細鍏宠仈搴撳缓璁爺绌秗outers/router.go鏂囦欢涓殑StaticFS锛屾坊鍔犲涓嬩唬鐮侊細r.StaticFS("/qrcode",http.Dir(qrcode.GetQrCodeFullPath()))楠岃瘉瀹屾暣鐨刄RL璺緞锛岃繑鍥炲悎鎴愬悗鐨勬捣鎶ュ拰浜岀淮鐮佹壂鎻忔垚鍔熸槸姝g‘鐨勶紝濡傛灉浣犳兂鐢ㄥソ鍥惧儚澶勭悊鍔熻兘锛屼綘蹇呴』浜嗚В鐩稿簲鐨勬€濊矾锛屼妇涓€鍙嶄笁锛屾渶鍚庡笇鏈涘浣犳湁鎵€甯姪銆傦紙1)搴忓垪鍖?鏋勫缓鍗氬API(2)搴忓垪鍖?鏋勫缓鍗氬API(3)搴忓垪鍖?浣跨敤JWT杩涜韬唤楠岃瘉搴忓垪鍖?缂栧啓涓€涓畝鍗曠殑鏂囦欢鏃ュ織搴忓垪鍖?Golang浼橀泤鍦伴噸鍚疕TTP鏈嶅姟搴忓垪鍖?涓哄叾娣诲姞Swagger搴忓垪鍖?.閮ㄧ讲鍘籰ang搴旂敤鍒癉ocker搴忓垪鍖?0.鑷畾涔塆ORM鍥炶皟搴忓垪鍖?1.Cron瀹氭椂浠诲姟搴忊€嬧€嬪垪鍖?2.浼樺寲閰嶇疆缁撴瀯瀹炵幇鍥剧墖涓婁紶搴忓垪鍖?3.浼樺寲搴旂敤缁撴瀯瀹炵幇Redis缂撳瓨搴忓垪鍖?4.瀹炵幇瀵煎嚭瀵煎叆Excel搴忓垪鍖?05.鐢熸垚浜岀淮鐮佸悎骞舵捣鎶ヨ繛杞?6.鍦ㄥ浘鐗囦笂缁樺埗鏂囧瓧杩炶浇17.浣跨敤Nginx閮ㄧ讲Go搴旂敤