mirror of
https://github.com/celogeek/go-comic-converter.git
synced 2025-05-25 16:22:37 +02:00
add algo for RGB to GrayScale
This commit is contained in:
parent
5a22932d02
commit
96c7d761ee
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
17
main.go
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user