diff --git a/internal/converter/converter.go b/internal/converter/converter.go index fc40ce9..3b47242 100644 --- a/internal/converter/converter.go +++ b/internal/converter/converter.go @@ -84,6 +84,12 @@ func (c *Converter) AddIntParam(p *int, name string, value int, usage string) { c.order = append(c.order, converterOrderName{value: name}) } +// Add an float parameter +func (c *Converter) AddFloatParam(p *float64, name string, value float64, usage string) { + c.Cmd.Float64Var(p, name, value, usage) + c.order = append(c.order, converterOrderName{value: name}) +} + // Add a boolean parameter func (c *Converter) AddBoolParam(p *bool, name string, value bool, usage string) { c.Cmd.BoolVar(p, name, value, usage) @@ -121,6 +127,7 @@ func (c *Converter) InitParse() { c.AddStringParam(&c.Options.BackgroundColor, "background-color", c.Options.BackgroundColor, "Background color in hexa format RGB. Black=000, White=FFF, Light Gray=DDD, Dark Gray=777") c.AddBoolParam(&c.Options.NoResize, "noresize", c.Options.NoResize, "Do not reduce image size if exceed device size") c.AddStringParam(&c.Options.Format, "format", c.Options.Format, "Format of output images: jpeg (lossy), png (lossless)") + c.AddFloatParam(&c.Options.AspectRatio, "aspect-ratio", c.Options.AspectRatio, "Aspect ratio (height/width) of the output\n -1 = same as device\n 0 = same as source\n1.6 = amazon advice for kindle") c.AddSection("Default config") c.AddBoolParam(&c.Options.Show, "show", false, "Show your default parameters") @@ -351,6 +358,11 @@ func (c *Converter) Validate() error { return errors.New("format should be jpeg or png") } + // Aspect Ratio + if c.Options.AspectRatio < 0 && c.Options.AspectRatio != -1 { + return errors.New("aspect ratio should be: -1, 0, > 0") + } + return nil } diff --git a/internal/converter/options/converter_options.go b/internal/converter/options/converter_options.go index 3a39859..c685e6a 100644 --- a/internal/converter/options/converter_options.go +++ b/internal/converter/options/converter_options.go @@ -21,28 +21,29 @@ type Options struct { Title string `yaml:"-"` // Config - Profile string `yaml:"profile"` - Quality int `yaml:"quality"` - Grayscale bool `yaml:"grayscale"` - Crop bool `yaml:"crop"` - CropRatioLeft int `yaml:"crop_ratio_left"` - CropRatioUp int `yaml:"crop_ratio_up"` - CropRatioRight int `yaml:"crop_ratio_right"` - CropRatioBottom int `yaml:"crop_ratio_bottom"` - Brightness int `yaml:"brightness"` - Contrast int `yaml:"contrast"` - AutoRotate bool `yaml:"auto_rotate"` - AutoSplitDoublePage bool `yaml:"auto_split_double_page"` - NoBlankImage bool `yaml:"no_blank_image"` - Manga bool `yaml:"manga"` - HasCover bool `yaml:"has_cover"` - LimitMb int `yaml:"limit_mb"` - StripFirstDirectoryFromToc bool `yaml:"strip_first_directory_from_toc"` - SortPathMode int `yaml:"sort_path_mode"` - ForegroundColor string `yaml:"foreground_color"` - BackgroundColor string `yaml:"background_color"` - NoResize bool `yaml:"noresize"` - Format string `yaml:"format"` + Profile string `yaml:"profile"` + Quality int `yaml:"quality"` + Grayscale bool `yaml:"grayscale"` + Crop bool `yaml:"crop"` + CropRatioLeft int `yaml:"crop_ratio_left"` + CropRatioUp int `yaml:"crop_ratio_up"` + CropRatioRight int `yaml:"crop_ratio_right"` + CropRatioBottom int `yaml:"crop_ratio_bottom"` + Brightness int `yaml:"brightness"` + Contrast int `yaml:"contrast"` + AutoRotate bool `yaml:"auto_rotate"` + AutoSplitDoublePage bool `yaml:"auto_split_double_page"` + NoBlankImage bool `yaml:"no_blank_image"` + Manga bool `yaml:"manga"` + HasCover bool `yaml:"has_cover"` + LimitMb int `yaml:"limit_mb"` + StripFirstDirectoryFromToc bool `yaml:"strip_first_directory_from_toc"` + SortPathMode int `yaml:"sort_path_mode"` + ForegroundColor string `yaml:"foreground_color"` + BackgroundColor string `yaml:"background_color"` + NoResize bool `yaml:"noresize"` + Format string `yaml:"format"` + AspectRatio float64 `yaml:"aspect_ratio"` // Default Config Show bool `yaml:"-"` @@ -94,6 +95,7 @@ func New() *Options { BackgroundColor: "FFF", NoResize: false, Format: "jpeg", + AspectRatio: 0, profiles: profiles.New(), } } @@ -167,6 +169,13 @@ func (o *Options) ShowConfig() string { sortpathmode = "path=alphanum, file=alphanum" } + aspectRatio := "auto" + if o.AspectRatio > 0 { + aspectRatio = fmt.Sprintf("1:%.02f", o.AspectRatio) + } else if o.AspectRatio < 0 { + aspectRatio = fmt.Sprintf("1:%0.2f (device)", float64(profile.Height)/float64(profile.Width)) + } + var b strings.Builder for _, v := range []struct { Key string @@ -192,6 +201,7 @@ func (o *Options) ShowConfig() string { {"Foreground Color", fmt.Sprintf("#%s", o.ForegroundColor), true}, {"Background Color", fmt.Sprintf("#%s", o.BackgroundColor), true}, {"Resize", !o.NoResize, true}, + {"Aspect Ratio", aspectRatio, true}, } { if v.Condition { b.WriteString(fmt.Sprintf("\n %-26s: %v", v.Key, v.Value)) diff --git a/internal/epub/epub.go b/internal/epub/epub.go index 633c361..9e6af84 100644 --- a/internal/epub/epub.go +++ b/internal/epub/epub.go @@ -194,8 +194,7 @@ func (e *ePub) getTree(images []*epubimage.Image, skip_files bool) string { return c.WriteString("") } -func (e *ePub) ComputeViewPort(epubParts []*epubPart) { - // readjusting view port +func (e *ePub) computeAspectRatio(epubParts []*epubPart) float64 { var ( bestAspectRatio float64 bestAspectRatioCount int @@ -209,7 +208,7 @@ func (e *ePub) ComputeViewPort(epubParts []*epubPart) { for _, p := range epubParts { aspectRatio[trunc(p.Cover.OriginalAspectRatio)]++ for _, i := range p.Images { - aspectRatio[trunc(i.OriginalAspectRatio)/100]++ + aspectRatio[trunc(i.OriginalAspectRatio)]++ } } @@ -219,6 +218,20 @@ func (e *ePub) ComputeViewPort(epubParts []*epubPart) { } } + return bestAspectRatio +} + +func (e *ePub) computeViewPort(epubParts []*epubPart) { + if e.Image.View.AspectRatio == -1 { + return //keep device size + } + + // readjusting view port + bestAspectRatio := e.Image.View.AspectRatio + if bestAspectRatio == 0 { + bestAspectRatio = e.computeAspectRatio(epubParts) + } + viewWidth, viewHeight := int(float64(e.Image.View.Height)/bestAspectRatio), int(float64(e.Image.View.Width)*bestAspectRatio) if viewWidth > e.Image.View.Width { e.Image.View.Height = viewHeight @@ -265,7 +278,7 @@ func (e *ePub) Write() error { Quiet: e.Quiet, }) - e.ComputeViewPort(epubParts) + e.computeViewPort(epubParts) for i, part := range epubParts { ext := filepath.Ext(e.Output) suffix := "" diff --git a/internal/epub/options/epub_options.go b/internal/epub/options/epub_options.go index 427852e..7f6cc42 100644 --- a/internal/epub/options/epub_options.go +++ b/internal/epub/options/epub_options.go @@ -16,6 +16,7 @@ type Color struct { type View struct { Width, Height int + AspectRatio float64 Color Color } diff --git a/main.go b/main.go index 441c8ad..0db43e5 100644 --- a/main.go +++ b/main.go @@ -130,8 +130,9 @@ $ go install github.com/celogeek/go-comic-converter/v%d@%s Manga: cmd.Options.Manga, HasCover: cmd.Options.HasCover, View: &epuboptions.View{ - Width: profile.Width, - Height: profile.Height, + Width: profile.Width, + Height: profile.Height, + AspectRatio: cmd.Options.AspectRatio, Color: epuboptions.Color{ Foreground: cmd.Options.ForegroundColor, Background: cmd.Options.BackgroundColor,