mirror of
https://github.com/gen2brain/cbconvert
synced 2026-07-24 20:36:12 +02:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0439a2edde | ||
|
|
92c49290ae | ||
|
|
7f025aa9c2 |
@@ -70,6 +70,8 @@ Commands:
|
||||
Image height (default "0")
|
||||
--fit
|
||||
Best fit for required width and height (default "false")
|
||||
--no-upscale
|
||||
Do not upscale images already smaller than the requested width/height (default "false")
|
||||
--dpi
|
||||
Document rendering resolution in DPI (PDF, EPUB, etc.), 0 uses the default (300) (default "0")
|
||||
--format
|
||||
@@ -126,6 +128,8 @@ Commands:
|
||||
Image height (default "0")
|
||||
--fit
|
||||
Best fit for required width and height (default "false")
|
||||
--no-upscale
|
||||
Do not upscale images already smaller than the requested width/height (default "false")
|
||||
--dpi
|
||||
Document rendering resolution in DPI (PDF, EPUB, etc.), 0 uses the default (300) (default "0")
|
||||
--format
|
||||
@@ -156,6 +160,8 @@ Commands:
|
||||
Image height (default "0")
|
||||
--fit
|
||||
Best fit for required width and height (default "false")
|
||||
--no-upscale
|
||||
Do not upscale images already smaller than the requested width/height (default "false")
|
||||
--dpi
|
||||
Document rendering resolution in DPI (PDF, EPUB, etc.), 0 uses the default (300) (default "0")
|
||||
--filter
|
||||
|
||||
+5
-10
@@ -39,6 +39,8 @@ type Options struct {
|
||||
Height int
|
||||
// Best fit for required width and height
|
||||
Fit bool
|
||||
// Do not upscale images already smaller than the requested width/height
|
||||
NoUpscale bool
|
||||
// Document rendering resolution in DPI (PDF, EPUB, etc.); 0 uses the default
|
||||
DPI int
|
||||
// 0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos
|
||||
@@ -180,6 +182,7 @@ func (o Options) Args() []string {
|
||||
num("width", o.Width, def.Width)
|
||||
num("height", o.Height, def.Height)
|
||||
flag("fit", o.Fit)
|
||||
flag("no-upscale", o.NoUpscale)
|
||||
num("dpi", o.DPI, def.DPI)
|
||||
str("format", o.Format, def.Format)
|
||||
str("archive", o.Archive, def.Archive)
|
||||
@@ -360,11 +363,7 @@ func (c *Converter) Cover(file File) error {
|
||||
}
|
||||
|
||||
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
||||
if c.Opts.Fit {
|
||||
cover = fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||
} else {
|
||||
cover = resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||
}
|
||||
cover = c.resizeFit(cover)
|
||||
}
|
||||
|
||||
ext := c.Opts.Format
|
||||
@@ -409,11 +408,7 @@ func (c *Converter) Thumbnail(file File) error {
|
||||
}
|
||||
|
||||
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
||||
if c.Opts.Fit {
|
||||
cover = fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||
} else {
|
||||
cover = resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||
}
|
||||
cover = c.resizeFit(cover)
|
||||
} else {
|
||||
cover = resize(cover, 256, 0, filters[c.Opts.Filter])
|
||||
}
|
||||
|
||||
@@ -326,11 +326,7 @@ func (c *Converter) imageTransform(img image.Image) image.Image {
|
||||
var i = img
|
||||
|
||||
if c.Opts.Width > 0 || c.Opts.Height > 0 {
|
||||
if c.Opts.Fit {
|
||||
i = fit(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||
} else {
|
||||
i = resize(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||
}
|
||||
i = c.resizeFit(i)
|
||||
}
|
||||
|
||||
if c.Opts.Rotate > 0 {
|
||||
|
||||
@@ -86,6 +86,26 @@ func fit(img image.Image, width, height int, filter transform.ResampleFilter) *i
|
||||
return resize(img, dstW, dstH, filter)
|
||||
}
|
||||
|
||||
// withinBounds reports whether img already fits within width by height; a zero dimension is unbounded.
|
||||
func withinBounds(img image.Image, width, height int) bool {
|
||||
b := img.Bounds()
|
||||
|
||||
return (width == 0 || b.Dx() <= width) && (height == 0 || b.Dy() <= height)
|
||||
}
|
||||
|
||||
// resizeFit resizes img to the configured width/height, honoring Fit and NoUpscale.
|
||||
func (c *Converter) resizeFit(img image.Image) image.Image {
|
||||
if c.Opts.Fit {
|
||||
return fit(img, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||
}
|
||||
|
||||
if c.Opts.NoUpscale && withinBounds(img, c.Opts.Width, c.Opts.Height) {
|
||||
return img
|
||||
}
|
||||
|
||||
return resize(img, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter])
|
||||
}
|
||||
|
||||
func rotate(img image.Image, angle float64) *image.RGBA {
|
||||
return transform.Rotate(img, angle, &transform.RotationOptions{ResizeBounds: true, Pivot: &image.Point{}})
|
||||
}
|
||||
|
||||
+52
-1
@@ -114,17 +114,68 @@ func TestArgs(t *testing.T) {
|
||||
opts.Effort = 4
|
||||
opts.Lossless = true
|
||||
opts.Width = 1200
|
||||
opts.NoUpscale = true
|
||||
opts.DPI = 150
|
||||
opts.Grayscale = true
|
||||
opts.OutDir = "/out"
|
||||
|
||||
got := strings.Join(opts.Args(), " ")
|
||||
want := "--width 1200 --dpi 150 --format webp --quality 90 --effort 4 --lossless --grayscale --outdir /out"
|
||||
want := "--width 1200 --no-upscale --dpi 150 --format webp --quality 90 --effort 4 --lossless --grayscale --outdir /out"
|
||||
if got != want {
|
||||
t.Errorf("Args() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoUpscale(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp(os.TempDir(), "cbc")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
width := func(o Options) int {
|
||||
conv := New(o)
|
||||
files, err := conv.Files([]string{"testdata/test.cbz"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, file := range files {
|
||||
if err := conv.Convert(file); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
return firstPage(t, conv, filepath.Join(tmpDir, "test.cbz")).Bounds().Dx()
|
||||
}
|
||||
|
||||
base := NewOptions()
|
||||
base.OutDir = tmpDir
|
||||
orig := width(base)
|
||||
|
||||
up := NewOptions()
|
||||
up.OutDir = tmpDir
|
||||
up.Width = orig * 2
|
||||
up.NoUpscale = true
|
||||
if got := width(up); got != orig {
|
||||
t.Errorf("NoUpscale should keep original width %d, got %d", orig, got)
|
||||
}
|
||||
|
||||
no := NewOptions()
|
||||
no.OutDir = tmpDir
|
||||
no.Width = orig * 2
|
||||
if got := width(no); got != orig*2 {
|
||||
t.Errorf("without NoUpscale should upscale to %d, got %d", orig*2, got)
|
||||
}
|
||||
|
||||
down := NewOptions()
|
||||
down.OutDir = tmpDir
|
||||
down.Width = orig / 2
|
||||
down.NoUpscale = true
|
||||
if got := width(down); got != orig/2 {
|
||||
t.Errorf("NoUpscale should still downscale to %d, got %d", orig/2, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertDPI(t *testing.T) {
|
||||
tmpDir, err := os.MkdirTemp(os.TempDir(), "cbc")
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
package main
|
||||
|
||||
import "github.com/gen2brain/iup-go/iup"
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gen2brain/cbconvert"
|
||||
"github.com/gen2brain/iup-go/iup"
|
||||
)
|
||||
|
||||
func fileDlg(title string, multiple, directory bool, dirKey string) ([]string, error) {
|
||||
ret := make([]string, 0)
|
||||
@@ -21,7 +28,12 @@ func fileDlg(title string, multiple, directory bool, dirKey string) ([]string, e
|
||||
"EXTFILTER": "Comic Files|*.rar;*.zip;*.7z;*.tar;*.cbr;*.cbz;*.cb7;*.cbt;*.pdf;*.epub;*.mobi;*.docx;*.pptx|",
|
||||
"FILTER": "*.cb*", // for Motif
|
||||
"TITLE": title,
|
||||
"SHOWPREVIEW": "YES",
|
||||
"PREVIEWWIDTH": "240",
|
||||
"PREVIEWHEIGHT": "320",
|
||||
})
|
||||
|
||||
dlg.SetCallback("FILE_CB", iup.FileFunc(previewCover()))
|
||||
} else {
|
||||
dlg.SetAttributes(map[string]string{
|
||||
"DIALOGTYPE": "DIR",
|
||||
@@ -55,6 +67,86 @@ func fileDlg(title string, multiple, directory bool, dirKey string) ([]string, e
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
const dlgPreviewName = "_FILEDLGPREVIEW_"
|
||||
|
||||
// previewCover returns a FILE_CB handler that draws the highlighted comic's cover in the dialog preview pane.
|
||||
func previewCover() iup.FileFunc {
|
||||
var image iup.Ihandle
|
||||
var lastFile string
|
||||
|
||||
return func(ih iup.Ihandle, filename, status string) int {
|
||||
switch status {
|
||||
case "PAINT":
|
||||
iup.DrawBegin(ih)
|
||||
cw, ch := iup.DrawGetSize(ih)
|
||||
iup.DrawParentBackground(ih)
|
||||
|
||||
if filename != lastFile {
|
||||
lastFile = filename
|
||||
if image != 0 {
|
||||
image.Destroy()
|
||||
image = 0
|
||||
}
|
||||
if img := loadCover(filename, cw, ch); img != 0 {
|
||||
image = img
|
||||
iup.SetHandle(dlgPreviewName, image)
|
||||
}
|
||||
}
|
||||
|
||||
if image != 0 {
|
||||
iw, iih, _ := iup.DrawGetImageInfo(dlgPreviewName)
|
||||
iup.DrawImage(ih, dlgPreviewName, (cw-iw)/2, (ch-iih)/2, iw, iih)
|
||||
} else {
|
||||
ih.SetAttribute("DRAWCOLOR", "128 128 128")
|
||||
tw, th := iup.DrawGetTextSize(ih, "No preview")
|
||||
iup.DrawText(ih, "No preview", (cw-tw)/2, (ch-th)/2, 0, 0)
|
||||
}
|
||||
|
||||
iup.DrawEnd(ih)
|
||||
case "FINISH":
|
||||
if image != 0 {
|
||||
image.Destroy()
|
||||
image = 0
|
||||
}
|
||||
lastFile = ""
|
||||
}
|
||||
|
||||
return iup.DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
// loadCover extracts the cover of a comic file and returns it as an IUP image fitted to w by h, or 0.
|
||||
func loadCover(path string, w, h int) iup.Ihandle {
|
||||
if w <= 0 || h <= 0 || !isComic(path) {
|
||||
return 0
|
||||
}
|
||||
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil || fi.IsDir() {
|
||||
return 0
|
||||
}
|
||||
|
||||
opts := cbconvert.NewOptions()
|
||||
opts.DPI = 96
|
||||
|
||||
img, err := cbconvert.New(opts).Preview(path, fi, w, h)
|
||||
if err != nil || img.Image == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
return iup.ImageFromImage(img.Image)
|
||||
}
|
||||
|
||||
func isComic(path string) bool {
|
||||
switch strings.ToLower(filepath.Ext(path)) {
|
||||
case ".rar", ".zip", ".7z", ".tar", ".cbr", ".cbz", ".cb7", ".cbt",
|
||||
".pdf", ".xps", ".epub", ".mobi", ".docx", ".pptx", ".xlsx":
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func saveDlg(title, dirKey string) string {
|
||||
dlg := iup.FileDlg()
|
||||
defer dlg.Destroy()
|
||||
|
||||
@@ -25,6 +25,7 @@ func options() cbconvert.Options {
|
||||
opts.Height = iup.GetHandle("Height").GetInt("VALUE")
|
||||
opts.DPI = dpiValue(iup.GetHandle("DPI").GetAttribute("VALUE"))
|
||||
opts.Fit = iup.GetHandle("Fit").GetAttribute("VALUE") == "ON"
|
||||
opts.NoUpscale = iup.GetHandle("NoUpscale").GetAttribute("VALUE") == "ON"
|
||||
opts.Filter = iup.GetHandle("Filter").GetInt("VALUE") - 1
|
||||
opts.Quality = iup.GetHandle("Quality").GetInt("VALUE")
|
||||
switch opts.Format {
|
||||
|
||||
@@ -39,6 +39,7 @@ var settings = []setting{
|
||||
{"NoNonImage", kindBool, "OFF"},
|
||||
{"Combine", kindBool, "OFF"},
|
||||
{"Fit", kindBool, "OFF"},
|
||||
{"NoUpscale", kindBool, "OFF"},
|
||||
{"Lossless", kindBool, "OFF"},
|
||||
{"Grayscale", kindBool, "OFF"},
|
||||
{"OutDir", kindStr, ""},
|
||||
|
||||
@@ -359,6 +359,8 @@ func tabImage() iup.Ihandle {
|
||||
iup.Vbox(
|
||||
iup.Toggle(" Best Fit").SetHandle("Fit").
|
||||
SetAttributes(`TIP="Best fit for required width and height"`),
|
||||
iup.Toggle(" No Upscale").SetHandle("NoUpscale").
|
||||
SetAttribute("TIP", "Do not enlarge images already smaller than the requested size"),
|
||||
),
|
||||
iup.Vbox(
|
||||
iup.Label("Resize Filter:"),
|
||||
|
||||
@@ -5,6 +5,7 @@ go 1.26
|
||||
require (
|
||||
github.com/gen2brain/cbconvert v1.0.5-0.20260623161611-a5817c3ba5de
|
||||
github.com/schollz/progressbar/v3 v3.19.0
|
||||
golang.org/x/term v0.44.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -52,7 +53,6 @@ require (
|
||||
golang.org/x/net v0.56.0 // indirect
|
||||
golang.org/x/sync v0.21.0 // indirect
|
||||
golang.org/x/sys v0.46.0 // indirect
|
||||
golang.org/x/term v0.44.0 // indirect
|
||||
golang.org/x/text v0.38.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
+44
-24
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"github.com/gen2brain/cbconvert"
|
||||
pb "github.com/schollz/progressbar/v3"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
var appVersion string
|
||||
@@ -78,39 +79,55 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
interactive := !opts.Quiet && term.IsTerminal(int(os.Stderr.Fd()))
|
||||
|
||||
var bar *pb.ProgressBar
|
||||
if opts.Cover || opts.Thumbnail || opts.Meta {
|
||||
if !opts.Quiet {
|
||||
bar = pb.NewOptions(conv.Nfiles,
|
||||
pb.OptionShowCount(),
|
||||
pb.OptionClearOnFinish(),
|
||||
pb.OptionUseANSICodes(true),
|
||||
pb.OptionSetPredictTime(false),
|
||||
)
|
||||
newBar := func(max int, description string) {
|
||||
bar = pb.NewOptions(max,
|
||||
pb.OptionShowCount(),
|
||||
pb.OptionClearOnFinish(),
|
||||
pb.OptionUseANSICodes(true),
|
||||
pb.OptionSetPredictTime(false),
|
||||
pb.OptionSetDescription(description),
|
||||
)
|
||||
}
|
||||
|
||||
clearLine := func() {
|
||||
fmt.Fprint(os.Stderr, "\033[2K\r")
|
||||
}
|
||||
|
||||
cleanup := func() {
|
||||
if interactive {
|
||||
if bar != nil {
|
||||
_ = bar.Finish()
|
||||
}
|
||||
clearLine()
|
||||
}
|
||||
}
|
||||
|
||||
if interactive && (opts.Cover || opts.Thumbnail || opts.Meta) {
|
||||
newBar(conv.Nfiles, "")
|
||||
}
|
||||
|
||||
conv.OnStart = func() {
|
||||
if !opts.Quiet {
|
||||
bar = pb.NewOptions(conv.Ncontents,
|
||||
pb.OptionShowCount(),
|
||||
pb.OptionClearOnFinish(),
|
||||
pb.OptionUseANSICodes(true),
|
||||
pb.OptionSetDescription(fmt.Sprintf("Converting %d of %d:", conv.CurrFile, conv.Nfiles)),
|
||||
pb.OptionSetPredictTime(false),
|
||||
)
|
||||
if interactive {
|
||||
clearLine()
|
||||
newBar(conv.Ncontents, fmt.Sprintf("Converting %d of %d:", conv.CurrFile, conv.Nfiles))
|
||||
}
|
||||
}
|
||||
|
||||
conv.OnProgress = func() {
|
||||
if !opts.Quiet {
|
||||
if bar != nil {
|
||||
_ = bar.Add(1)
|
||||
}
|
||||
}
|
||||
|
||||
conv.OnCompress = func() {
|
||||
if !opts.Quiet {
|
||||
fmt.Fprintf(os.Stderr, "Compressing %d of %d...\r", conv.CurrFile, conv.Nfiles)
|
||||
if interactive {
|
||||
if bar != nil {
|
||||
_ = bar.Finish()
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "Compressing %d of %d...", conv.CurrFile, conv.Nfiles)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +137,7 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "\r")
|
||||
cleanup()
|
||||
|
||||
return
|
||||
}
|
||||
@@ -163,7 +180,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "\r")
|
||||
cleanup()
|
||||
}
|
||||
|
||||
// parseFlags parses command line flags.
|
||||
@@ -175,6 +192,7 @@ func parseFlags() (cbconvert.Options, []string) {
|
||||
convert.IntVar(&opts.Width, "width", 0, "Image width")
|
||||
convert.IntVar(&opts.Height, "height", 0, "Image height")
|
||||
convert.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
|
||||
convert.BoolVar(&opts.NoUpscale, "no-upscale", false, "Do not upscale images already smaller than the requested width/height")
|
||||
convert.IntVar(&opts.DPI, "dpi", 0, "Document rendering resolution in DPI (PDF, EPUB, etc.), 0 uses the default (300)")
|
||||
convert.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif, jxl")
|
||||
convert.StringVar(&opts.Archive, "archive", "zip", "Archive format, valid values are zip, tar")
|
||||
@@ -203,6 +221,7 @@ func parseFlags() (cbconvert.Options, []string) {
|
||||
cover.IntVar(&opts.Width, "width", 0, "Image width")
|
||||
cover.IntVar(&opts.Height, "height", 0, "Image height")
|
||||
cover.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
|
||||
cover.BoolVar(&opts.NoUpscale, "no-upscale", false, "Do not upscale images already smaller than the requested width/height")
|
||||
cover.IntVar(&opts.DPI, "dpi", 0, "Document rendering resolution in DPI (PDF, EPUB, etc.), 0 uses the default (300)")
|
||||
cover.StringVar(&opts.Format, "format", "jpeg", "Image format, valid values are jpeg, png, tiff, bmp, webp, avif")
|
||||
cover.IntVar(&opts.Quality, "quality", 75, "Image quality")
|
||||
@@ -218,6 +237,7 @@ func parseFlags() (cbconvert.Options, []string) {
|
||||
thumbnail.IntVar(&opts.Width, "width", 0, "Image width")
|
||||
thumbnail.IntVar(&opts.Height, "height", 0, "Image height")
|
||||
thumbnail.BoolVar(&opts.Fit, "fit", false, "Best fit for required width and height")
|
||||
thumbnail.BoolVar(&opts.NoUpscale, "no-upscale", false, "Do not upscale images already smaller than the requested width/height")
|
||||
thumbnail.IntVar(&opts.DPI, "dpi", 0, "Document rendering resolution in DPI (PDF, EPUB, etc.), 0 uses the default (300)")
|
||||
thumbnail.IntVar(&opts.Filter, "filter", 2, "0=NearestNeighbor, 1=Box, 2=Linear, 3=MitchellNetravali, 4=CatmullRom, 6=Gaussian, 7=Lanczos")
|
||||
thumbnail.StringVar(&opts.OutDir, "outdir", ".", "Output directory")
|
||||
@@ -239,7 +259,7 @@ func parseFlags() (cbconvert.Options, []string) {
|
||||
fmt.Fprintf(os.Stderr, "Usage: %s <command> [<flags>] [file1 dir1 ... fileOrDirN]\n\n", filepath.Base(os.Args[0]))
|
||||
fmt.Fprintf(os.Stderr, "\nCommands:\n")
|
||||
fmt.Fprintf(os.Stderr, "\n convert\n \tConvert archive or document\n\n")
|
||||
order := []string{"width", "height", "fit", "dpi", "format", "archive", "zip-level", "quality", "effort", "lossless", "combine", "outfile", "filter", "no-cover", "no-rgb",
|
||||
order := []string{"width", "height", "fit", "no-upscale", "dpi", "format", "archive", "zip-level", "quality", "effort", "lossless", "combine", "outfile", "filter", "no-cover", "no-rgb",
|
||||
"no-nonimage", "no-convert", "grayscale", "rotate", "brightness", "contrast", "suffix", "outdir", "size", "recursive", "quiet"}
|
||||
for _, name := range order {
|
||||
f := convert.Lookup(name)
|
||||
@@ -247,14 +267,14 @@ func parseFlags() (cbconvert.Options, []string) {
|
||||
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "\n cover\n \tExtract cover\n\n")
|
||||
order = []string{"width", "height", "fit", "dpi", "format", "quality", "effort", "lossless", "filter", "outdir", "size", "recursive", "quiet"}
|
||||
order = []string{"width", "height", "fit", "no-upscale", "dpi", "format", "quality", "effort", "lossless", "filter", "outdir", "size", "recursive", "quiet"}
|
||||
for _, name := range order {
|
||||
f := cover.Lookup(name)
|
||||
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||
fmt.Fprintf(os.Stderr, "%v (default %q)\n", f.Usage, f.DefValue)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "\n thumbnail\n \tExtract cover thumbnail (freedesktop spec.)\n\n")
|
||||
order = []string{"width", "height", "fit", "dpi", "filter", "outdir", "outfile", "size", "recursive", "quiet"}
|
||||
order = []string{"width", "height", "fit", "no-upscale", "dpi", "filter", "outdir", "outfile", "size", "recursive", "quiet"}
|
||||
for _, name := range order {
|
||||
f := thumbnail.Lookup(name)
|
||||
fmt.Fprintf(os.Stderr, " --%s\n \t", f.Name)
|
||||
|
||||
Reference in New Issue
Block a user