From f77005128a391025c16fb65c47a4272ac003cbf1 Mon Sep 17 00:00:00 2001 From: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com> Date: Thu, 8 Aug 2024 17:12:13 +0000 Subject: [performance] move thumbnail generation to go code where possible (#3183) * wrap thumbnailing code to handle generation natively where possible * more code comments! * add even more code comments! * add code comments about blurhash generation * maintain image rotation if contained in exif data * move rotation before resizing * ensure pix_fmt actually selected by ffprobe, check for alpha layer with gifs * use linear instead of nearest-neighbour for resizing * work with image "orientation" instead of "rotation". use default 75% quality for both webp and jpeg generation * add header to new file * use thumb extension when getting thumb mime type * update test models and tests with new media processing * add suggested code comments * add note about thumbnail filter count reducing memory usage --- internal/media/processingmedia.go | 65 ++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 29 deletions(-) (limited to 'internal/media/processingmedia.go') diff --git a/internal/media/processingmedia.go b/internal/media/processingmedia.go index 1d286bda7..b89bbb41d 100644 --- a/internal/media/processingmedia.go +++ b/internal/media/processingmedia.go @@ -230,31 +230,26 @@ func (p *ProcessingMedia) store(ctx context.Context) error { p.media.FileMeta.Small.Size = (thumbWidth * thumbHeight) p.media.FileMeta.Small.Aspect = aspect - // Generate a thumbnail image from input image path. - thumbpath, err = ffmpegGenerateThumb(ctx, temppath, + // Determine if blurhash needs generating. + needBlurhash := (p.media.Blurhash == "") + var newBlurhash string + + // Generate thumbnail, and new blurhash if need from media. + thumbpath, newBlurhash, err = generateThumb(ctx, temppath, thumbWidth, thumbHeight, + result.orientation, + result.PixFmt(), + needBlurhash, ) if err != nil { return gtserror.Newf("error generating image thumb: %w", err) } - if p.media.Blurhash == "" { - // Generate blurhash (if not already) from thumbnail. - p.media.Blurhash, err = generateBlurhash(thumbpath) - if err != nil { - return gtserror.Newf("error generating thumb blurhash: %w", err) - } + if needBlurhash { + // Set newly determined blurhash. + p.media.Blurhash = newBlurhash } - - // Calculate final media attachment thumbnail path. - p.media.Thumbnail.Path = uris.StoragePathForAttachment( - p.media.AccountID, - string(TypeAttachment), - string(SizeSmall), - p.media.ID, - "webp", - ) } // Calculate final media attachment file path. @@ -279,6 +274,18 @@ func (p *ProcessingMedia) store(ctx context.Context) error { p.media.File.FileSize = int(filesz) if thumbpath != "" { + // Determine final thumbnail ext. + thumbExt := getExtension(thumbpath) + + // Calculate final media attachment thumbnail path. + p.media.Thumbnail.Path = uris.StoragePathForAttachment( + p.media.AccountID, + string(TypeAttachment), + string(SizeSmall), + p.media.ID, + thumbExt, + ) + // Copy thumbnail file into storage at path. thumbsz, err := p.mgr.state.Storage.PutFile(ctx, p.media.Thumbnail.Path, @@ -290,6 +297,18 @@ func (p *ProcessingMedia) store(ctx context.Context) error { // Set final determined thumbnail size. p.media.Thumbnail.FileSize = int(thumbsz) + + // Determine thumbnail content-type from thumb ext. + p.media.Thumbnail.ContentType = getMimeType(thumbExt) + + // Generate a media attachment thumbnail URL. + p.media.Thumbnail.URL = uris.URIForAttachment( + p.media.AccountID, + string(TypeAttachment), + string(SizeSmall), + p.media.ID, + thumbExt, + ) } // Generate a media attachment URL. @@ -301,22 +320,10 @@ func (p *ProcessingMedia) store(ctx context.Context) error { ext, ) - // Generate a media attachment thumbnail URL. - p.media.Thumbnail.URL = uris.URIForAttachment( - p.media.AccountID, - string(TypeAttachment), - string(SizeSmall), - p.media.ID, - "webp", - ) - // Get mimetype for the file container // type, falling back to generic data. p.media.File.ContentType = getMimeType(ext) - // Set the known thumbnail content type. - p.media.Thumbnail.ContentType = "image/webp" - // We can now consider this cached. p.media.Cached = util.Ptr(true) -- cgit v1.2.3