From 6088af7101661c6e808b1d782586d6022d667799 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Sat, 28 Jan 2023 08:21:01 -0500 Subject: [PATCH] avoid gif conversion --- audon-fe/src/stores/counter.js | 12 ------- avatar.go | 57 +++++++++++++++++++++------------- room.go | 8 +++-- 3 files changed, 41 insertions(+), 36 deletions(-) delete mode 100644 audon-fe/src/stores/counter.js diff --git a/audon-fe/src/stores/counter.js b/audon-fe/src/stores/counter.js deleted file mode 100644 index 374b4d0..0000000 --- a/audon-fe/src/stores/counter.js +++ /dev/null @@ -1,12 +0,0 @@ -import { ref, computed } from "vue"; -import { defineStore } from "pinia"; - -export const useCounterStore = defineStore("counter", () => { - const count = ref(0); - const doubleCount = computed(() => count.value * 2); - function increment() { - count.value++; - } - - return { count, doubleCount, increment }; -}); diff --git a/avatar.go b/avatar.go index d46b520..b66ab2a 100644 --- a/avatar.go +++ b/avatar.go @@ -22,18 +22,20 @@ import ( "gopkg.in/gographics/imagick.v2/imagick" ) -func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte, room *Room) ([]byte, []byte, error) { +func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte, room *Room) (indicator []byte, original []byte, isGIF bool, err error) { + isGIF = false + if u == nil { - return nil, nil, errors.New("nil user") + err = errors.New("nil user") + return } mtype := mimetype.Detect(fnew) if !mimetype.EqualsAny(mtype.String(), "image/png", "image/jpeg", "image/webp", "image/gif") { - return nil, nil, errors.New("file type not supported") + err = errors.New("file type not supported") + return } - var err error - buf := bytes.NewReader(fnew) var newImg image.Image @@ -45,29 +47,40 @@ func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte, room *Room) ( newImg, err = webp.Decode(buf) } else if mtype.Is("image/gif") { newImg, err = gif.Decode(buf) + isGIF = true } if err != nil { - return nil, nil, err + return } - // encode to png to avoid recompression - origBuf := new(bytes.Buffer) - if err := png.Encode(origBuf, newImg); err != nil { - return nil, nil, err + // encode to png to avoid recompression, except GIF + var origImg []byte + if !isGIF { + origBuf := new(bytes.Buffer) + if err = png.Encode(origBuf, newImg); err != nil { + return + } + origImg = origBuf.Bytes() + } else { + origImg = fnew } - origPng := origBuf.Bytes() - hash := sha256.Sum256(origPng) + hash := sha256.Sum256(origImg) // Check if user's original avatar exists - filename := fmt.Sprintf("%x.png", hash) + var filename string + if isGIF { + filename = fmt.Sprintf("%x.gif", hash) + } else { + filename = fmt.Sprintf("%x.png", hash) + } saved := u.getAvatarImagePath(filename) - if _, err := os.Stat(saved); err != nil { - if err := os.MkdirAll(filepath.Dir(saved), 0775); err != nil { - return nil, nil, err + if _, err = os.Stat(saved); err != nil { + if err = os.MkdirAll(filepath.Dir(saved), 0775); err != nil { + return } // Write user's avatar if the original version doesn't exist - if err := os.WriteFile(saved, origPng, 0664); err != nil { - return nil, nil, err + if err = os.WriteFile(saved, origImg, 0664); err != nil { + return } } @@ -77,15 +90,15 @@ func (u *AudonUser) GetIndicator(ctx context.Context, fnew []byte, room *Room) ( bson.D{ {Key: "$set", Value: bson.D{{Key: "avatar", Value: filename}}}, }); err != nil { - return nil, nil, err + return } - indicator, err := u.createGIF(newImg, room.IsHost(u) || room.IsCoHost(u)) + indicator, err = u.createGIF(newImg, room.IsHost(u) || room.IsCoHost(u)) if err != nil { - return nil, nil, err + return } - return indicator, origPng, nil + return indicator, origImg, isGIF, nil } func (u *AudonUser) createGIF(avatar image.Image, blue bool) ([]byte, error) { diff --git a/room.go b/room.go index 4631e0a..5de163b 100644 --- a/room.go +++ b/room.go @@ -423,12 +423,16 @@ func joinRoomHandler(c echo.Context) (err error) { } // Generate indicator GIF - indicator, original, err := user.GetIndicator(c.Request().Context(), fnew, room) + indicator, original, isGIF, err := user.GetIndicator(c.Request().Context(), fnew, room) + origMime := "image/png" + if isGIF { + origMime = "image/gif" + } if err != nil { c.Logger().Error(err) return echo.NewHTTPError(http.StatusInternalServerError) } - resp.Original = fmt.Sprintf("data:image/png;base64,%s", base64.StdEncoding.EncodeToString(original)) + resp.Original = fmt.Sprintf("data:%s;base64,%s", origMime, base64.StdEncoding.EncodeToString(original)) resp.Indicator = fmt.Sprintf("data:image/gif;base64,%s", base64.StdEncoding.EncodeToString(indicator)) } else if err != nil { c.Logger().Error(err)