feat(backend): switch to libvips for avatar resizing
This commit is contained in:
		
							parent
							
								
									9c4e29e64f
								
							
						
					
					
						commit
						1319366637
					
				
					 4 changed files with 30 additions and 25 deletions
				
			
		|  | @ -6,19 +6,15 @@ import ( | |||
| 	"crypto/sha256" | ||||
| 	"encoding/base64" | ||||
| 	"encoding/hex" | ||||
| 	"image" | ||||
| 	_ "image/gif" | ||||
| 	"image/jpeg" | ||||
| 	_ "image/png" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"emperror.dev/errors" | ||||
| 	"github.com/disintegration/imaging" | ||||
| 	"github.com/davidbyttow/govips/v2/vips" | ||||
| 	"github.com/minio/minio-go/v7" | ||||
| 	"github.com/rs/xid" | ||||
| 
 | ||||
| 	"github.com/chai2010/webp" | ||||
| ) | ||||
| 
 | ||||
| const ErrInvalidDataURI = errors.Sentinel("invalid data URI") | ||||
|  | @ -30,6 +26,8 @@ func (db *DB) ConvertAvatar(data string) ( | |||
| 	jpgOut *bytes.Buffer, | ||||
| 	err error, | ||||
| ) { | ||||
| 	defer vips.ShutdownThread() | ||||
| 
 | ||||
| 	data = strings.TrimSpace(data) | ||||
| 	if !strings.Contains(data, ",") || !strings.Contains(data, ":") || !strings.Contains(data, ";") { | ||||
| 		return nil, nil, ErrInvalidDataURI | ||||
|  | @ -41,28 +39,31 @@ func (db *DB) ConvertAvatar(data string) ( | |||
| 		return nil, nil, errors.Wrap(err, "invalid base64 data") | ||||
| 	} | ||||
| 
 | ||||
| 	img, _, err := image.Decode(bytes.NewReader(rawData)) | ||||
| 	image, err := vips.LoadImageFromBuffer(rawData, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, errors.Wrap(err, "decoding image") | ||||
| 	} | ||||
| 
 | ||||
| 	resized := imaging.Fill(img, 512, 512, imaging.Center, imaging.Linear) | ||||
| 
 | ||||
| 	webpOut = new(bytes.Buffer) | ||||
| 	err = webp.Encode(webpOut, resized, &webp.Options{ | ||||
| 		Quality: 90, | ||||
| 	}) | ||||
| 	err = image.ThumbnailWithSize(512, 512, vips.InterestingCentre, vips.SizeBoth) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, errors.Wrap(err, "encoding WebP image") | ||||
| 		return nil, nil, errors.Wrap(err, "resizing image") | ||||
| 	} | ||||
| 
 | ||||
| 	jpgOut = new(bytes.Buffer) | ||||
| 	err = jpeg.Encode(jpgOut, resized, &jpeg.Options{ | ||||
| 		Quality: 80, | ||||
| 	}) | ||||
| 	webpExport := vips.NewWebpExportParams() | ||||
| 	webpExport.Quality = 90 | ||||
| 	webpB, _, err := image.ExportWebp(webpExport) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, errors.Wrap(err, "encoding JPEG image") | ||||
| 		return nil, nil, errors.Wrap(err, "exporting webp image") | ||||
| 	} | ||||
| 	webpOut = bytes.NewBuffer(webpB) | ||||
| 
 | ||||
| 	jpegExport := vips.NewJpegExportParams() | ||||
| 	jpegExport.Quality = 80 | ||||
| 	jpegB, _, err := image.ExportJpeg(jpegExport) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, errors.Wrap(err, "exporting jpeg image") | ||||
| 	} | ||||
| 	jpgOut = bytes.NewBuffer(jpegB) | ||||
| 
 | ||||
| 	return webpOut, jpgOut, nil | ||||
| } | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ import ( | |||
| 	"codeberg.org/u1f320/pronouns.cc/backend/log" | ||||
| 	"codeberg.org/u1f320/pronouns.cc/backend/server" | ||||
| 
 | ||||
| 	"github.com/davidbyttow/govips/v2/vips" | ||||
| 	"github.com/go-chi/render" | ||||
| 	_ "github.com/joho/godotenv/autoload" | ||||
| 	"github.com/urfave/cli/v2" | ||||
|  | @ -22,6 +23,9 @@ var Command = &cli.Command{ | |||
| } | ||||
| 
 | ||||
| func run(c *cli.Context) error { | ||||
| 	vips.Startup(nil) | ||||
| 	defer vips.Shutdown() | ||||
| 
 | ||||
| 	port := ":" + os.Getenv("PORT") | ||||
| 
 | ||||
| 	s, err := server.New() | ||||
|  |  | |||
							
								
								
									
										3
									
								
								go.mod
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
										
									
									
									
								
							|  | @ -6,8 +6,7 @@ require ( | |||
| 	emperror.dev/errors v0.8.1 | ||||
| 	github.com/Masterminds/squirrel v1.5.4 | ||||
| 	github.com/bwmarrin/discordgo v0.27.1 | ||||
| 	github.com/chai2010/webp v1.1.1 | ||||
| 	github.com/disintegration/imaging v1.6.2 | ||||
| 	github.com/davidbyttow/govips/v2 v2.13.0 | ||||
| 	github.com/georgysavva/scany/v2 v2.0.0 | ||||
| 	github.com/go-chi/chi/v5 v5.0.8 | ||||
| 	github.com/go-chi/cors v1.2.1 | ||||
|  |  | |||
							
								
								
									
										11
									
								
								go.sum
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								go.sum
									
										
									
									
									
								
							|  | @ -78,8 +78,6 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf | |||
| github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||||
| github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= | ||||
| github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= | ||||
| github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk= | ||||
| github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU= | ||||
| github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= | ||||
| github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= | ||||
| github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= | ||||
|  | @ -106,11 +104,11 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 | |||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/davidbyttow/govips/v2 v2.13.0 h1:5MK9ZcXZC5GzUR9Ca8fJwOYqMgll/H096ec0PJP59QM= | ||||
| github.com/davidbyttow/govips/v2 v2.13.0/go.mod h1:LPTrwWtNa5n4yl9UC52YBOEGdZcY5hDTP4Ms2QWasTw= | ||||
| github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= | ||||
| github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= | ||||
| github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= | ||||
| github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= | ||||
| github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= | ||||
| github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= | ||||
| github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= | ||||
| github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= | ||||
|  | @ -389,6 +387,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY | |||
| github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | ||||
| github.com/nelsam/hel/v2 v2.3.2/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w= | ||||
| github.com/nelsam/hel/v2 v2.3.3/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy+rL3w= | ||||
| github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= | ||||
| github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= | ||||
| github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= | ||||
| github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= | ||||
|  | @ -555,7 +554,7 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH | |||
| golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= | ||||
| golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= | ||||
| golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||||
| golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= | ||||
| golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= | ||||
| golang.org/x/image v0.6.0 h1:bR8b5okrPI3g/gyZakLZHeWxAR8Dn5CyxXv1hLH5g/4= | ||||
| golang.org/x/image v0.6.0/go.mod h1:MXLdDR43H7cDJq5GEGXEVeeNhPgi+YYEQ2pC1byI1x0= | ||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
|  | @ -628,6 +627,7 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug | |||
| golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= | ||||
| golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= | ||||
| golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||||
| golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= | ||||
| golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= | ||||
| golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= | ||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||||
|  | @ -921,6 +921,7 @@ google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw | |||
| gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= | ||||
| gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= | ||||
| gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue