Skip to content

Commit

Permalink
Fix encoding of thumbnails
Browse files Browse the repository at this point in the history
  • Loading branch information
chongyangshi committed Jun 8, 2019
1 parent 396a6f5 commit 50cad5b
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 26 deletions.
53 changes: 30 additions & 23 deletions thumbnail/thumbnail.go
@@ -1,7 +1,6 @@
package thumbnail

import (
"bufio"
"bytes"
"context"
"fmt"
Expand All @@ -13,25 +12,31 @@ import (
"os"
"path"
"strings"
"sync"

"github.com/monzo/slog"
"github.com/nfnt/resize"

"github.com/icydoge/yronwood/config"
)

const thumbnailWidth = 200
const thumbnailWidth = 800

var thumbnailPathMutex = sync.Mutex{}

func GetThumbnailForImage(ctx context.Context, fileName, storagePath, accessType string) ([]byte, error) {
thumbnailPath := config.ConfigStorageDirectoryThumbnail
thumbnailPathMutex.Lock()
if _, err := os.Stat(thumbnailPath); os.IsNotExist(err) {
slog.Info(ctx, "Thumbnail directory %s does not exist, attempting to create it", thumbnailPath)
mkdirErr := os.Mkdir(config.ConfigStorageDirectoryThumbnail, 0755)
if mkdirErr != nil {
slog.Error(ctx, "Could not create non-existing storage directory %s: %v", thumbnailPath, err)
thumbnailPathMutex.Unlock()
return nil, mkdirErr
}
}
thumbnailPathMutex.Unlock()

thumbnailFilePath := path.Join(thumbnailPath, getThumbnailFileName(fileName, accessType))
if _, err := os.Stat(thumbnailFilePath); err == nil {
Expand Down Expand Up @@ -71,19 +76,23 @@ func GetThumbnailForImage(ctx context.Context, fileName, storagePath, accessType
return nil, err
}

thumbnail := resize.Thumbnail(thumbnailWidth, 0, img, resize.Lanczos3)
encodedThumbnail, err := encodeImage(fileName, thumbnail)
thumbnail := resize.Resize(thumbnailWidth, 0, img, resize.Lanczos3)
thumbnailFilePath, err = encodeImageToFile(fileName, thumbnailPath, accessType, thumbnail)
if err != nil {
slog.Debug(ctx, "Could not encode thumbnail of image %s: %v", filePath, err)
return nil, err
}

if err = ioutil.WriteFile(getThumbnailFileName(fileName, accessType), encodedThumbnail, 0644); err != nil {
slog.Debug(ctx, "Could not write thumbnail of image %s: %v", filePath, err)
return nil, err
if thumbnailFilePath != "" {
file, err := ioutil.ReadFile(thumbnailFilePath)
if err != nil {
slog.Debug(ctx, "Could not read thumnnail %s: %v", thumbnailFilePath, err)
return nil, err
}
return file, nil
}

return encodedThumbnail, nil
return nil, nil
}

func getThumbnailFileName(fileName, accessType string) string {
Expand All @@ -94,7 +103,7 @@ func getThumbnailFileName(fileName, accessType string) string {

name := strings.Join(fileNameComponents[0:len(fileNameComponents)-1], ".")
extension := fileNameComponents[len(fileNameComponents)-1]
thumbnailFileName := fmt.Sprintf("%s_%s.%s", name, "thumb", extension)
thumbnailFileName := fmt.Sprintf("%s_%s_%s.%s", name, accessType, "thumb", extension)

return thumbnailFileName
}
Expand All @@ -118,31 +127,29 @@ func decodeImage(fileName string, filePayload []byte) (image.Image, error) {
return nil, nil
}

func encodeImage(fileName string, img image.Image) ([]byte, error) {
func encodeImageToFile(fileName, storagePath, accessType string, img image.Image) (string, error) {
fileNameComponents := strings.Split(fileName, ".")
if len(fileNameComponents) < 2 {
return nil, nil
return "", nil
}
extension := fileNameComponents[len(fileNameComponents)-1]

var buf = bytes.Buffer{}
imageWriter := bufio.NewWriter(&buf)
thumbnailPath := path.Join(storagePath, getThumbnailFileName(fileName, accessType))
thumbnailFile, err := os.Create(thumbnailPath)
if err != nil {
return "", err
}
defer thumbnailFile.Close()

var encodeErr error
switch strings.ToLower(extension) {
case "jpg", "jpeg":
encodeErr = jpeg.Encode(imageWriter, img, nil)
encodeErr = jpeg.Encode(thumbnailFile, img, nil)
case "png":
encodeErr = png.Encode(imageWriter, img)
encodeErr = png.Encode(thumbnailFile, img)
case "gif":
encodeErr = gif.Encode(imageWriter, img, nil)
}

flushErr := imageWriter.Flush()
if encodeErr != nil || flushErr != nil {
return nil, encodeErr
encodeErr = gif.Encode(thumbnailFile, img, nil)
}

imageReader := bufio.NewReader(&buf)
return ioutil.ReadAll(imageReader)
return thumbnailPath, encodeErr
}
34 changes: 31 additions & 3 deletions web/yronwood/static/yronwood.js
Expand Up @@ -46,12 +46,15 @@ function list_images(access_type, page) {
$("#images-container").append(current_row);
row_size = 0;
}
var image_link = API_BASE + "/uploads/" + encodeURIComponent(image.access_path) + "/" + encodeURIComponent(image.file_name)
var image_link = API_BASE + "/uploads/" + encodeURIComponent(image.access_path) + "/" + encodeURIComponent(image.file_name) + '?'
var secret = get_basic_auth_token();
if (secret != null && secret != "") {
image_link += "?token=" + encodeURIComponent(secret)
image_link = insertParam(image_link, "token", encodeURIComponent(secret))
}
$(current_row).append("<div class='col-sm grid-image'><a target='_blank' href='"+ image_link + "'><img class='grid-image' src='" + image_link +"?thumbnail=yes' /></a></div>");

thumbnail_link = insertParam(image_link, "thumbnail", "yes")
$(current_row).append("<div class='col-sm grid-image'><a target='_blank' href='"+ image_link + "'><img class='grid-image' src='" + thumbnail_link +"' /></a></div>");

row_size++;
}
}
Expand Down Expand Up @@ -237,4 +240,29 @@ function randomFileName(length) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}

// Adapted from https://stackoverflow.com/a/487049
function insertParam(url, key, value)
{
key = encodeURI(key); value = encodeURI(value);

var kvp = url.split('&');
var i=kvp.length; var x; while(i--)
{
x = kvp[i].split('=');

if (x[0]==key)
{
x[1] = value;
kvp[i] = x.join('=');
break;
}
}

if (i<0) {
kvp[kvp.length] = [key,value].join('=');
}

return kvp.join('&');
}

0 comments on commit 50cad5b

Please sign in to comment.