Skip to content

Commit

Permalink
Merge pull request #18 from shermp/thumbnail-rez
Browse files Browse the repository at this point in the history
Switch thumbnail image resize library
  • Loading branch information
shermp authored May 27, 2019
2 parents 2df531b + ea618b4 commit a49abba
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 16 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module github.com/shermp/Kobo-UNCaGED

require (
github.com/disintegration/imaging v1.6.0
github.com/bamiaux/rez v0.0.0-20170731184118-29f4463c688b
github.com/gofrs/uuid v3.2.0+incompatible
github.com/kapmahc/epub v0.1.1
github.com/mattn/go-sqlite3 v1.10.0
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/bamiaux/rez v0.0.0-20170731184118-29f4463c688b h1:5Ci5wpOL75rYF6RQGRoqhEAU6xLJ6n/D4SckXX1yB74=
github.com/bamiaux/rez v0.0.0-20170731184118-29f4463c688b/go.mod h1:obBQGGIFbbv9KWg92Qu9UHeD94JXmHD1jovY/z6I3O8=
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/disintegration/imaging v1.6.0 h1:nVPXRUUQ36Z7MNf0O77UzgnOb1mkMMor7lmJMJXc/mA=
github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/kapmahc/epub v0.1.1 h1:a4fgmhh/q2vyzFR2QXOVohR2zAuQvbacCjMZ1LGr0lw=
Expand All @@ -20,8 +20,6 @@ github.com/shermp/UNCaGED/uc v0.2.0 h1:SeN0ZY6blq4IRaBAmK2wkvOJN3OPpRaxM2oLq3zX3
github.com/shermp/UNCaGED/uc v0.2.0/go.mod h1:y9yAhXj5BN5S2EC8GTGlnUo0gX1q4JhkDQ70zRQGGSE=
github.com/shermp/go-fbink-v2 v1.15.1 h1:CvLsaXxpKF1nYnqRvU7QKAjooZvCM/HhyjkLV7LsMjg=
github.com/shermp/go-fbink-v2 v1.15.1/go.mod h1:88bOAwruwze/4JB/KW8uoyPtWm5OPa1BZEraFMHJgpQ=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81 h1:00VmoueYNlNz/aHIilyyQz/MHSqGoWJzpFv/HW8xpzI=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
Expand Down
17 changes: 16 additions & 1 deletion kobo-uncaged/ku.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,19 @@ preferKepub = true
passwordList = []

# Provide more verbose logging
enableDebug = false
enableDebug = false

# The following options tweak aspects of the thumbnail generation process
[thumbnail]
# Choose what level of thumbnails you want generated. Options are "all", "partial", "none"
# "all" generates all thumbnails, including that used on the sleep screen.
# "partial" generates thumbnails used in the library views and home screen, and is faster than "all"
# "none" generates no thumbnails, and let's the Kobo software generate them.
generateLevel = "all"

# Choose which resize algorithm to use when generating thumbnails. Allowed options are
# "bilinear", "bicubic", "lanczos2", "lanczos3". Default is "bicubic"
resizeAlgorithm = "bicubic"

# Choose a Jpeg quality level between 0 and 100. Default is 90
jpegQuality = 90
59 changes: 59 additions & 0 deletions kobo-uncaged/kutypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
"fmt"
"image"
"path/filepath"
"strings"

"github.com/bamiaux/rez"
)

type cidPrefix string
Expand Down Expand Up @@ -209,3 +212,59 @@ func (k koboCover) RelPath(imageID string) string {
dir1, dir2, basename := hashedImageParts(imageID)
return filepath.Join(dir1, dir2, fmt.Sprintf("%s - %s.parsed", basename, k.String()))
}

type thumbnailOption struct {
GenerateLevel string
ResizeAlgorithm string
JpegQuality int
rezFilter rez.Filter
}

const (
generateAll string = "all"
generatePartial string = "partial"
generateNone string = "none"
)

const (
//resizeNN string = "nearest"
resizeBL string = "bilinear"
resizeBC string = "bicubic"
resizeLC2 string = "lanczos2"
resizeLC3 string = "lanczos3"
)

func (to *thumbnailOption) validate() {
switch strings.ToLower(to.GenerateLevel) {
case generateAll, generatePartial, generateNone:
to.GenerateLevel = strings.ToLower(to.GenerateLevel)
default:
to.GenerateLevel = generateAll
}

switch strings.ToLower(to.ResizeAlgorithm) {
case resizeBL, resizeBC, resizeLC2, resizeLC3:
to.ResizeAlgorithm = strings.ToLower(to.ResizeAlgorithm)
default:
to.ResizeAlgorithm = resizeBC
}

if to.JpegQuality < 1 || to.JpegQuality > 100 {
to.JpegQuality = 90
}
}

func (to *thumbnailOption) setRezFilter() {
switch to.ResizeAlgorithm {
case resizeBL:
to.rezFilter = rez.NewBilinearFilter()
case resizeBC:
to.rezFilter = rez.NewBicubicFilter()
case resizeLC2:
to.rezFilter = rez.NewLanczosFilter(2)
case resizeLC3:
to.rezFilter = rez.NewLanczosFilter(3)
default:
to.rezFilter = rez.NewBicubicFilter()
}
}
45 changes: 35 additions & 10 deletions kobo-uncaged/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"fmt"
"html"
"image"
"image/jpeg"
"io"
"io/ioutil"
"log"
Expand All @@ -38,7 +39,7 @@ import (
"syscall"
"time"

"github.com/disintegration/imaging"
"github.com/bamiaux/rez"
"github.com/gofrs/uuid"
"github.com/kapmahc/epub"
_ "github.com/mattn/go-sqlite3"
Expand Down Expand Up @@ -97,6 +98,7 @@ type KoboUncaged struct {
PreferKepub bool
PasswordList []string
EnableDebug bool
Thumbnail thumbnailOption
}
dbRootDir string
bkRootDir string
Expand Down Expand Up @@ -147,6 +149,8 @@ func New(dbRootDir, sdRootDir string, updatingMD bool) (*KoboUncaged, error) {
log.Print(err)
return nil, err
}
ku.KuConfig.Thumbnail.validate()
ku.KuConfig.Thumbnail.setRezFilter()

if sdRootDir != "" && ku.KuConfig.PreferSDCard {
ku.useSDCard = true
Expand Down Expand Up @@ -480,7 +484,7 @@ func (ku *KoboUncaged) saveDeviceInfo() error {
func (ku *KoboUncaged) saveCoverImage(contentID string, size image.Point, imgB64 string) {
defer ku.wg.Done()

img, err := imaging.Decode(base64.NewDecoder(base64.StdEncoding, strings.NewReader(imgB64)))
img, _, err := image.Decode(base64.NewDecoder(base64.StdEncoding, strings.NewReader(imgB64)))
if err != nil {
log.Println(err)
return
Expand All @@ -492,21 +496,35 @@ func (ku *KoboUncaged) saveCoverImage(contentID string, size image.Point, imgB64
imgDir = "koboExtStorage/images-cache"
}
imgDir = filepath.Join(ku.bkRootDir, imgDir)

imgID := imgIDFromContentID(contentID)
jpegOpts := jpeg.Options{Quality: ku.KuConfig.Thumbnail.JpegQuality}

for _, cover := range []koboCover{fullCover, libFull, libGrid} {
var coverEndings []koboCover
switch ku.KuConfig.Thumbnail.GenerateLevel {
case generateAll:
coverEndings = []koboCover{fullCover, libFull, libGrid}
case generatePartial:
coverEndings = []koboCover{libFull, libGrid}
}
for _, cover := range coverEndings {
nsz := cover.Resize(ku.device, sz)
nfn := filepath.Join(imgDir, cover.RelPath(imgID))

log.Printf("Resizing %s cover to %s (target %s) for %s\n", sz, nsz, cover.Size(ku.device), cover)

nimg := img
var nimg image.Image
if !sz.Eq(nsz) {
nimg = imaging.Resize(nimg, nsz.X, nsz.Y, imaging.Linear)
nimg = image.NewYCbCr(image.Rect(0, 0, nsz.X, nsz.Y), img.(*image.YCbCr).SubsampleRatio)
rez.Convert(nimg, img, ku.KuConfig.Thumbnail.rezFilter)
log.Printf(" -- Resized to %s\n", nimg.Bounds().Size())
} else {
nimg = img
log.Println(" -- Skipped resize: already correct size")
}
// Optimization. No need to resize libGrid from the full cover size...
if cover == libFull {
img = nimg
}

if err := os.MkdirAll(filepath.Dir(nfn), 0755); err != nil {
log.Println(err)
Expand All @@ -519,7 +537,7 @@ func (ku *KoboUncaged) saveCoverImage(contentID string, size image.Point, imgB64
continue
}

if err := imaging.Encode(lf, nimg, imaging.JPEG); err != nil {
if err := jpeg.Encode(lf, nimg, &jpegOpts); err != nil {
log.Println(err)
lf.Close()
}
Expand Down Expand Up @@ -578,8 +596,16 @@ func (ku *KoboUncaged) GetClientOptions() uc.ClientOptions {
opts.SupportedExt = append(opts.SupportedExt, ext...)
opts.DeviceName = "Kobo"
opts.DeviceModel = ku.device.Model()
fc := fullCover.Size(ku.device)
opts.CoverDims.Width, opts.CoverDims.Height = fc.X, fc.Y
var thumbSz image.Point
switch ku.KuConfig.Thumbnail.GenerateLevel {
case generateAll:
thumbSz = fullCover.Size(ku.device)
case generatePartial:
thumbSz = libFull.Size(ku.device)
default:
thumbSz = libGrid.Size(ku.device)
}
opts.CoverDims.Width, opts.CoverDims.Height = thumbSz.X, thumbSz.Y
return opts
}

Expand Down Expand Up @@ -861,7 +887,6 @@ func mainWithErrCode() returnCode {
return kuError
}
log.Println("Starting Calibre Connection")
ku.kup.kuPrintln(body, "Finishing up")
err = cc.Start()
if err != nil {
if err.Error() == "no password entered" {
Expand Down

0 comments on commit a49abba

Please sign in to comment.