add algo for RGB to GrayScale

This commit is contained in:
Celogeek 2022-12-30 18:20:38 +01:00
parent 5a22932d02
commit 96c7d761ee
Signed by: celogeek
GPG Key ID: E6B7BDCFC446233A
5 changed files with 64 additions and 6 deletions

View File

@ -76,6 +76,8 @@ The ePub include as a first page:
# go-comic-converter -h # go-comic-converter -h
Usage of go-comic-converter: Usage of go-comic-converter:
-algo string
Algo for RGB to Grayscale: luster, default, mean, luma (default "default")
-author string -author string
Author of the epub (default "GO Comic Converter") Author of the epub (default "GO Comic Converter")
-input string -input string

View File

@ -15,6 +15,7 @@ type ImageOptions struct {
ViewWidth int ViewWidth int
ViewHeight int ViewHeight int
Quality int Quality int
Algo string
} }
type EpubOptions struct { type EpubOptions struct {

View File

@ -80,6 +80,7 @@ func LoadImages(path string, options *ImageOptions) ([]*Image, error) {
options.ViewWidth, options.ViewWidth,
options.ViewHeight, options.ViewHeight,
options.Quality, options.Quality,
options.Algo,
) )
name := fmt.Sprintf("OEBPS/Images/%d.jpg", img.Id) name := fmt.Sprintf("OEBPS/Images/%d.jpg", img.Id)
if img.Id == 0 { if img.Id == 0 {

View File

@ -6,11 +6,50 @@ import (
"image/color" "image/color"
"image/jpeg" "image/jpeg"
"io" "io"
"sort"
"golang.org/x/image/draw" "golang.org/x/image/draw"
) )
func Load(reader io.ReadCloser) *image.Gray { var AlgoGray = map[string]func(color.Color) color.Color{
"default": func(c color.Color) color.Color {
return color.GrayModel.Convert(c)
},
"mean": func(c color.Color) color.Color {
r, g, b, _ := c.RGBA()
y := float64(r+g+b) / 3 * (255.0 / 65535)
return color.Gray{uint8(y)}
},
"luma": func(c color.Color) color.Color {
r, g, b, _ := c.RGBA()
y := (0.2126*float64(r) + 0.7152*float64(g) + 0.0722*float64(b)) * (255.0 / 65535)
return color.Gray{uint8(y)}
},
"luster": func(c color.Color) color.Color {
r, g, b, _ := c.RGBA()
arr := []float64{float64(r), float64(g), float64(b)}
sort.Float64s(arr)
y := (arr[0] + arr[2]) / 2 * (255.0 / 65535)
return color.Gray{uint8(y)}
},
}
func toGray(img image.Image, algo string) *image.Gray {
grayImg := image.NewGray(img.Bounds())
algoConv, ok := AlgoGray[algo]
if !ok {
panic("wrong gray algo")
}
for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ {
for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ {
grayImg.Set(x, y, algoConv(img.At(x, y)))
}
}
return grayImg
}
func Load(reader io.ReadCloser, algo string) *image.Gray {
defer reader.Close() defer reader.Close()
img, _, err := image.Decode(reader) img, _, err := image.Decode(reader)
if err != nil { if err != nil {
@ -21,9 +60,7 @@ func Load(reader io.ReadCloser) *image.Gray {
case *image.Gray: case *image.Gray:
return imgt return imgt
default: default:
newImg := image.NewGray(img.Bounds()) return toGray(img, algo)
draw.Draw(newImg, newImg.Bounds(), img, image.Point{}, draw.Src)
return newImg
} }
} }
@ -120,8 +157,8 @@ func Get(img *image.Gray, quality int) []byte {
return b.Bytes() return b.Bytes()
} }
func Convert(reader io.ReadCloser, crop bool, w, h int, quality int) ([]byte, int, int) { func Convert(reader io.ReadCloser, crop bool, w, h int, quality int, algo string) ([]byte, int, int) {
img := Load(reader) img := Load(reader, algo)
if crop { if crop {
img = CropMarging(img) img = CropMarging(img)
} }

17
main.go
View File

@ -7,6 +7,8 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
imageconverter "github.com/celogeek/go-comic-converter/internal/image-converter"
"github.com/celogeek/go-comic-converter/internal/epub" "github.com/celogeek/go-comic-converter/internal/epub"
) )
@ -61,6 +63,7 @@ type Option struct {
Title string Title string
Quality int Quality int
NoCrop bool NoCrop bool
Algo string
LimitMb int LimitMb int
} }
@ -88,6 +91,7 @@ Options:
Title : %s Title : %s
Quality : %d Quality : %d
Crop : %v Crop : %v
AlgoGray: %s
LimitMb : %s LimitMb : %s
`, `,
o.Input, o.Input,
@ -100,6 +104,7 @@ Options:
o.Title, o.Title,
o.Quality, o.Quality,
!o.NoCrop, !o.NoCrop,
o.Algo,
limitmb, limitmb,
) )
} }
@ -114,6 +119,10 @@ func main() {
p.Description, p.Description,
)) ))
} }
availableAlgo := make([]string, 0)
for a := range imageconverter.AlgoGray {
availableAlgo = append(availableAlgo, a)
}
opt := &Option{} opt := &Option{}
flag.StringVar(&opt.Input, "input", "", "Source of comic to convert: directory, cbz, zip, cbr, rar, pdf") flag.StringVar(&opt.Input, "input", "", "Source of comic to convert: directory, cbz, zip, cbr, rar, pdf")
@ -123,6 +132,7 @@ func main() {
flag.StringVar(&opt.Title, "title", "", "Title of the epub") flag.StringVar(&opt.Title, "title", "", "Title of the epub")
flag.IntVar(&opt.Quality, "quality", 85, "Quality of the image") flag.IntVar(&opt.Quality, "quality", 85, "Quality of the image")
flag.BoolVar(&opt.NoCrop, "nocrop", false, "Disable cropping") flag.BoolVar(&opt.NoCrop, "nocrop", false, "Disable cropping")
flag.StringVar(&opt.Algo, "algo", "default", fmt.Sprintf("Algo for RGB to Grayscale: %s", strings.Join(availableAlgo, ", ")))
flag.IntVar(&opt.LimitMb, "limitmb", 0, "Limit size of the ePub: Default nolimit (0), Minimum 20") flag.IntVar(&opt.LimitMb, "limitmb", 0, "Limit size of the ePub: Default nolimit (0), Minimum 20")
flag.Usage = func() { flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", filepath.Base(os.Args[0])) fmt.Fprintf(os.Stderr, "Usage of %s:\n", filepath.Base(os.Args[0]))
@ -192,6 +202,12 @@ func main() {
opt.Title = filepath.Base(defaultOutput[0 : len(defaultOutput)-len(ext)]) opt.Title = filepath.Base(defaultOutput[0 : len(defaultOutput)-len(ext)])
} }
if _, ok := imageconverter.AlgoGray[opt.Algo]; !ok {
fmt.Fprintln(os.Stderr, "algo doesn't exists")
flag.Usage()
os.Exit(1)
}
fmt.Fprintln(os.Stderr, opt) fmt.Fprintln(os.Stderr, opt)
if err := epub.NewEpub(&epub.EpubOptions{ if err := epub.NewEpub(&epub.EpubOptions{
@ -205,6 +221,7 @@ func main() {
ViewHeight: profile.Height, ViewHeight: profile.Height,
Quality: opt.Quality, Quality: opt.Quality,
Crop: !opt.NoCrop, Crop: !opt.NoCrop,
Algo: opt.Algo,
}, },
}).Write(); err != nil { }).Write(); err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) fmt.Fprintf(os.Stderr, "Error: %v\n", err)