mirror of
https://github.com/celogeek/go-comic-converter.git
synced 2025-05-25 08:12:36 +02:00
add png output images format
This commit is contained in:
parent
58cd5f5399
commit
a816350c97
@ -121,6 +121,7 @@ func (c *Converter) InitParse() {
|
|||||||
c.AddStringParam(&c.Options.ForegroundColor, "foreground-color", c.Options.ForegroundColor, "Foreground color in hexa format RGB. Black=000, White=FFF")
|
c.AddStringParam(&c.Options.ForegroundColor, "foreground-color", c.Options.ForegroundColor, "Foreground color in hexa format RGB. Black=000, White=FFF")
|
||||||
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.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.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.AddSection("Default config")
|
c.AddSection("Default config")
|
||||||
c.AddBoolParam(&c.Options.Show, "show", false, "Show your default parameters")
|
c.AddBoolParam(&c.Options.Show, "show", false, "Show your default parameters")
|
||||||
@ -318,6 +319,11 @@ func (c *Converter) Validate() error {
|
|||||||
return errors.New("background color must have color format in hexa: [0-9A-F]{3}")
|
return errors.New("background color must have color format in hexa: [0-9A-F]{3}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format
|
||||||
|
if !(c.Options.Format == "jpeg" || c.Options.Format == "png") {
|
||||||
|
return errors.New("format should be jpeg or png")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ type Options struct {
|
|||||||
ForegroundColor string `yaml:"foreground_color"`
|
ForegroundColor string `yaml:"foreground_color"`
|
||||||
BackgroundColor string `yaml:"background_color"`
|
BackgroundColor string `yaml:"background_color"`
|
||||||
NoResize bool `yaml:"noresize"`
|
NoResize bool `yaml:"noresize"`
|
||||||
|
Format string `yaml:"format"`
|
||||||
|
|
||||||
// Default Config
|
// Default Config
|
||||||
Show bool `yaml:"-"`
|
Show bool `yaml:"-"`
|
||||||
@ -86,6 +87,7 @@ func New() *Options {
|
|||||||
ForegroundColor: "000",
|
ForegroundColor: "000",
|
||||||
BackgroundColor: "FFF",
|
BackgroundColor: "FFF",
|
||||||
NoResize: false,
|
NoResize: false,
|
||||||
|
Format: "jpeg",
|
||||||
profiles: profiles.New(),
|
profiles: profiles.New(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -195,6 +197,7 @@ func (o *Options) ShowConfig() string {
|
|||||||
{"Foreground Color", fmt.Sprintf("#%s", o.ForegroundColor)},
|
{"Foreground Color", fmt.Sprintf("#%s", o.ForegroundColor)},
|
||||||
{"Background Color", fmt.Sprintf("#%s", o.BackgroundColor)},
|
{"Background Color", fmt.Sprintf("#%s", o.BackgroundColor)},
|
||||||
{"Resize", !o.NoResize},
|
{"Resize", !o.NoResize},
|
||||||
|
{"Format", o.Format},
|
||||||
} {
|
} {
|
||||||
b.WriteString(fmt.Sprintf("\n %-26s: %v", v.K, v.V))
|
b.WriteString(fmt.Sprintf("\n %-26s: %v", v.K, v.V))
|
||||||
}
|
}
|
||||||
|
@ -282,7 +282,7 @@ func (e *ePub) Write() error {
|
|||||||
{"OEBPS/Text/title.xhtml", e.render(epubtemplates.Text, map[string]any{
|
{"OEBPS/Text/title.xhtml", e.render(epubtemplates.Text, map[string]any{
|
||||||
"Title": title,
|
"Title": title,
|
||||||
"ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height),
|
"ViewPort": fmt.Sprintf("width=%d,height=%d", e.Image.View.Width, e.Image.View.Height),
|
||||||
"ImagePath": "Images/title.jpg",
|
"ImagePath": fmt.Sprintf("Images/title.%s", e.Image.Format),
|
||||||
"ImageStyle": part.Cover.ImgStyle(e.Image.View.Width, e.Image.View.Height, titleAlign),
|
"ImageStyle": part.Cover.ImgStyle(e.Image.View.Width, e.Image.View.Height, titleAlign),
|
||||||
})},
|
})},
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ type Image struct {
|
|||||||
Path string
|
Path string
|
||||||
Name string
|
Name string
|
||||||
Position string
|
Position string
|
||||||
|
Format string
|
||||||
}
|
}
|
||||||
|
|
||||||
// key name of the blank plage after the image
|
// key name of the blank plage after the image
|
||||||
@ -60,7 +61,7 @@ func (i *Image) ImgKey() string {
|
|||||||
|
|
||||||
// image path
|
// image path
|
||||||
func (i *Image) ImgPath() string {
|
func (i *Image) ImgPath() string {
|
||||||
return fmt.Sprintf("Images/%s.jpg", i.ImgKey())
|
return fmt.Sprintf("Images/%s.%s", i.ImgKey(), i.Format)
|
||||||
}
|
}
|
||||||
|
|
||||||
// image path into the EPUB
|
// image path into the EPUB
|
||||||
|
@ -38,9 +38,10 @@ func (e *EPUBImageProcessor) Load() (images []*epubimage.Image, err error) {
|
|||||||
if e.Dry {
|
if e.Dry {
|
||||||
for img := range imageInput {
|
for img := range imageInput {
|
||||||
images = append(images, &epubimage.Image{
|
images = append(images, &epubimage.Image{
|
||||||
Id: img.Id,
|
Id: img.Id,
|
||||||
Path: img.Path,
|
Path: img.Path,
|
||||||
Name: img.Name,
|
Name: img.Name,
|
||||||
|
Format: e.Image.Format,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,13 +60,17 @@ func (e *EPUBImageProcessor) Load() (images []*epubimage.Image, err error) {
|
|||||||
})
|
})
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
|
|
||||||
imgStorage, err := epubzip.NewEPUBZipStorageImageWriter(e.ImgStorage())
|
imgStorage, err := epubzip.NewEPUBZipStorageImageWriter(e.ImgStorage(), e.Image.Format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
bar.Close()
|
bar.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < e.WorkersRatio(50); i++ {
|
wr := 50
|
||||||
|
if e.Image.Format == "png" {
|
||||||
|
wr = 100
|
||||||
|
}
|
||||||
|
for i := 0; i < e.WorkersRatio(wr); i++ {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
@ -90,6 +95,7 @@ func (e *EPUBImageProcessor) Load() (images []*epubimage.Image, err error) {
|
|||||||
DoublePage: part == 0 && src.Bounds().Dx() > src.Bounds().Dy(),
|
DoublePage: part == 0 && src.Bounds().Dx() > src.Bounds().Dy(),
|
||||||
Path: input.Path,
|
Path: input.Path,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
|
Format: e.Image.Format,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = imgStorage.Add(img.EPUBImgPath(), dst, e.Image.Quality); err != nil {
|
if err = imgStorage.Add(img.EPUBImgPath(), dst, e.Image.Quality); err != nil {
|
||||||
@ -253,5 +259,10 @@ func (e *EPUBImageProcessor) CoverTitleData(src image.Image, title string) (*epu
|
|||||||
dst := e.createImage(src, g.Bounds(src.Bounds()))
|
dst := e.createImage(src, g.Bounds(src.Bounds()))
|
||||||
g.Draw(dst, src)
|
g.Draw(dst, src)
|
||||||
|
|
||||||
return epubzip.CompressImage("OEBPS/Images/title.jpg", dst, e.Image.Quality)
|
return epubzip.CompressImage(
|
||||||
|
fmt.Sprintf("OEBPS/Images/title.%s", e.Image.Format),
|
||||||
|
e.Image.Format,
|
||||||
|
dst,
|
||||||
|
e.Image.Quality,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ type Image struct {
|
|||||||
View *View
|
View *View
|
||||||
GrayScale bool
|
GrayScale bool
|
||||||
Resize bool
|
Resize bool
|
||||||
|
Format string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
|
@ -127,7 +127,7 @@ func getManifest(o *ContentOptions) []tag {
|
|||||||
var imageTags, pageTags, spaceTags []tag
|
var imageTags, pageTags, spaceTags []tag
|
||||||
addTag := func(img *epubimage.Image, withSpace bool) {
|
addTag := func(img *epubimage.Image, withSpace bool) {
|
||||||
imageTags = append(imageTags,
|
imageTags = append(imageTags,
|
||||||
tag{"item", tagAttrs{"id": img.ImgKey(), "href": img.ImgPath(), "media-type": "image/jpeg"}, ""},
|
tag{"item", tagAttrs{"id": img.ImgKey(), "href": img.ImgPath(), "media-type": fmt.Sprintf("image/%s", o.ImageOptions.Format)}, ""},
|
||||||
)
|
)
|
||||||
pageTags = append(pageTags,
|
pageTags = append(pageTags,
|
||||||
tag{"item", tagAttrs{"id": img.PageKey(), "href": img.PagePath(), "media-type": "application/xhtml+xml"}, ""},
|
tag{"item", tagAttrs{"id": img.PageKey(), "href": img.PagePath(), "media-type": "application/xhtml+xml"}, ""},
|
||||||
@ -144,7 +144,7 @@ func getManifest(o *ContentOptions) []tag {
|
|||||||
{"item", tagAttrs{"id": "css", "href": "Text/style.css", "media-type": "text/css"}, ""},
|
{"item", tagAttrs{"id": "css", "href": "Text/style.css", "media-type": "text/css"}, ""},
|
||||||
{"item", tagAttrs{"id": "space_title", "href": "Text/space_title.xhtml", "media-type": "application/xhtml+xml"}, ""},
|
{"item", tagAttrs{"id": "space_title", "href": "Text/space_title.xhtml", "media-type": "application/xhtml+xml"}, ""},
|
||||||
{"item", tagAttrs{"id": "page_title", "href": "Text/title.xhtml", "media-type": "application/xhtml+xml"}, ""},
|
{"item", tagAttrs{"id": "page_title", "href": "Text/title.xhtml", "media-type": "application/xhtml+xml"}, ""},
|
||||||
{"item", tagAttrs{"id": "img_title", "href": "Images/title.jpg", "media-type": "image/jpeg"}, ""},
|
{"item", tagAttrs{"id": "img_title", "href": fmt.Sprintf("Images/title.%s", o.ImageOptions.Format), "media-type": fmt.Sprintf("image/%s", o.ImageOptions.Format)}, ""},
|
||||||
}
|
}
|
||||||
|
|
||||||
if o.ImageOptions.HasCover || o.Current > 1 {
|
if o.ImageOptions.HasCover || o.Current > 1 {
|
||||||
|
@ -4,9 +4,11 @@ import (
|
|||||||
"archive/zip"
|
"archive/zip"
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/flate"
|
"compress/flate"
|
||||||
|
"fmt"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
"image"
|
"image"
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
|
"image/png"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,13 +18,20 @@ type ZipImage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create gzip encoded jpeg
|
// create gzip encoded jpeg
|
||||||
func CompressImage(filename string, img image.Image, quality int) (*ZipImage, error) {
|
func CompressImage(filename string, format string, img image.Image, quality int) (*ZipImage, error) {
|
||||||
var (
|
var (
|
||||||
data, cdata bytes.Buffer
|
data, cdata bytes.Buffer
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
err = jpeg.Encode(&data, img, &jpeg.Options{Quality: quality})
|
switch format {
|
||||||
|
case "png":
|
||||||
|
err = png.Encode(&data, img)
|
||||||
|
case "jpeg":
|
||||||
|
err = jpeg.Encode(&data, img, &jpeg.Options{Quality: quality})
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unknown format %q", format)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -8,19 +8,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type EPUBZipStorageImageWriter struct {
|
type EPUBZipStorageImageWriter struct {
|
||||||
fh *os.File
|
fh *os.File
|
||||||
fz *zip.Writer
|
fz *zip.Writer
|
||||||
|
format string
|
||||||
mut *sync.Mutex
|
mut *sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEPUBZipStorageImageWriter(filename string) (*EPUBZipStorageImageWriter, error) {
|
func NewEPUBZipStorageImageWriter(filename string, format string) (*EPUBZipStorageImageWriter, error) {
|
||||||
fh, err := os.Create(filename)
|
fh, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fz := zip.NewWriter(fh)
|
fz := zip.NewWriter(fh)
|
||||||
return &EPUBZipStorageImageWriter{fh, fz, &sync.Mutex{}}, nil
|
return &EPUBZipStorageImageWriter{fh, fz, format, &sync.Mutex{}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EPUBZipStorageImageWriter) Close() error {
|
func (e *EPUBZipStorageImageWriter) Close() error {
|
||||||
@ -32,7 +32,7 @@ func (e *EPUBZipStorageImageWriter) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *EPUBZipStorageImageWriter) Add(filename string, img image.Image, quality int) error {
|
func (e *EPUBZipStorageImageWriter) Add(filename string, img image.Image, quality int) error {
|
||||||
zipImage, err := CompressImage(filename, img, quality)
|
zipImage, err := CompressImage(filename, e.format, img, quality)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
1
main.go
1
main.go
@ -139,6 +139,7 @@ $ go install github.com/celogeek/go-comic-converter/v%d@%s
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Resize: !cmd.Options.NoResize,
|
Resize: !cmd.Options.NoResize,
|
||||||
|
Format: cmd.Options.Format,
|
||||||
},
|
},
|
||||||
}).Write(); err != nil {
|
}).Write(); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user