mirror of
https://github.com/celogeek/go-comic-converter.git
synced 2025-05-25 00:02:37 +02:00
add palette with algo, fix naming
This commit is contained in:
parent
c123e510b6
commit
d8da68cdc4
@ -2,6 +2,7 @@ package epub
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image/color"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
@ -16,6 +17,7 @@ type ImageOptions struct {
|
|||||||
ViewHeight int
|
ViewHeight int
|
||||||
Quality int
|
Quality int
|
||||||
Algo string
|
Algo string
|
||||||
|
Palette color.Palette
|
||||||
}
|
}
|
||||||
|
|
||||||
type EpubOptions struct {
|
type EpubOptions struct {
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
imageconverter "github.com/celogeek/go-comic-converter/internal/image-converter"
|
"github.com/celogeek/go-comic-converter/internal/imageconverter"
|
||||||
|
|
||||||
"github.com/nwaples/rardecode"
|
"github.com/nwaples/rardecode"
|
||||||
pdfimage "github.com/raff/pdfreader/image"
|
pdfimage "github.com/raff/pdfreader/image"
|
||||||
@ -81,6 +81,7 @@ func LoadImages(path string, options *ImageOptions) ([]*Image, error) {
|
|||||||
options.ViewHeight,
|
options.ViewHeight,
|
||||||
options.Quality,
|
options.Quality,
|
||||||
options.Algo,
|
options.Algo,
|
||||||
|
options.Palette,
|
||||||
)
|
)
|
||||||
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 {
|
||||||
|
29
internal/imageconverter/algo.go
Normal file
29
internal/imageconverter/algo.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package imageconverter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ALGO_GRAY = map[string]func(color.Color, color.Palette) color.Gray{
|
||||||
|
"default": func(c color.Color, p color.Palette) color.Gray {
|
||||||
|
return p.Convert(c).(color.Gray)
|
||||||
|
},
|
||||||
|
"mean": func(c color.Color, p color.Palette) color.Gray {
|
||||||
|
r, g, b, _ := c.RGBA()
|
||||||
|
y := float64(r+g+b) / 3
|
||||||
|
return p.Convert(color.Gray16{Y: uint16(y)}).(color.Gray)
|
||||||
|
},
|
||||||
|
"luma": func(c color.Color, p color.Palette) color.Gray {
|
||||||
|
r, g, b, _ := c.RGBA()
|
||||||
|
y := (0.2126*float64(r) + 0.7152*float64(g) + 0.0722*float64(b))
|
||||||
|
return p.Convert(color.Gray16{Y: uint16(y)}).(color.Gray)
|
||||||
|
},
|
||||||
|
"luster": func(c color.Color, p color.Palette) color.Gray {
|
||||||
|
r, g, b, _ := c.RGBA()
|
||||||
|
arr := []float64{float64(r), float64(g), float64(b)}
|
||||||
|
sort.Float64s(arr)
|
||||||
|
y := (arr[0] + arr[2]) / 2
|
||||||
|
return p.Convert(color.Gray16{Y: uint16(y)}).(color.Gray)
|
||||||
|
},
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package comicconverter
|
package imageconverter
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -6,62 +6,29 @@ import (
|
|||||||
"image/color"
|
"image/color"
|
||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
|
||||||
|
|
||||||
"golang.org/x/image/draw"
|
"golang.org/x/image/draw"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AlgoGray = map[string]func(color.Color) color.Gray{
|
func Load(reader io.ReadCloser, algo string, palette color.Palette) *image.Gray {
|
||||||
"default": func(c color.Color) color.Gray {
|
|
||||||
return color.GrayModel.Convert(c).(color.Gray)
|
|
||||||
},
|
|
||||||
"mean": func(c color.Color) color.Gray {
|
|
||||||
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.Gray {
|
|
||||||
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.Gray {
|
|
||||||
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.SetGray(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 {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
algoFunc, ok := ALGO_GRAY[algo]
|
||||||
switch imgt := img.(type) {
|
if !ok {
|
||||||
case *image.Gray:
|
panic("unknown algo")
|
||||||
return imgt
|
|
||||||
default:
|
|
||||||
return toGray(img, algo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grayImg := image.NewGray(img.Bounds())
|
||||||
|
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.SetGray(x, y, algoFunc(img.At(x, y), palette))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return grayImg
|
||||||
}
|
}
|
||||||
|
|
||||||
func isBlank(c color.Color) bool {
|
func isBlank(c color.Color) bool {
|
||||||
@ -157,8 +124,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, algo string) ([]byte, int, int) {
|
func Convert(reader io.ReadCloser, crop bool, w, h int, quality int, algo string, palette color.Palette) ([]byte, int, int) {
|
||||||
img := Load(reader, algo)
|
img := Load(reader, algo, palette)
|
||||||
if crop {
|
if crop {
|
||||||
img = CropMarging(img)
|
img = CropMarging(img)
|
||||||
}
|
}
|
45
internal/imageconverter/palette.go
Normal file
45
internal/imageconverter/palette.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package imageconverter
|
||||||
|
|
||||||
|
import "image/color"
|
||||||
|
|
||||||
|
var PALETTE_16 = color.Palette{
|
||||||
|
color.Gray{0x00},
|
||||||
|
color.Gray{0x11},
|
||||||
|
color.Gray{0x22},
|
||||||
|
color.Gray{0x33},
|
||||||
|
color.Gray{0x44},
|
||||||
|
color.Gray{0x55},
|
||||||
|
color.Gray{0x66},
|
||||||
|
color.Gray{0x77},
|
||||||
|
color.Gray{0x88},
|
||||||
|
color.Gray{0x99},
|
||||||
|
color.Gray{0xaa},
|
||||||
|
color.Gray{0xbb},
|
||||||
|
color.Gray{0xcc},
|
||||||
|
color.Gray{0xdd},
|
||||||
|
color.Gray{0xff},
|
||||||
|
}
|
||||||
|
|
||||||
|
var PALETTE_15 = color.Palette{
|
||||||
|
color.Gray{0x00},
|
||||||
|
color.Gray{0x11},
|
||||||
|
color.Gray{0x22},
|
||||||
|
color.Gray{0x33},
|
||||||
|
color.Gray{0x44},
|
||||||
|
color.Gray{0x55},
|
||||||
|
color.Gray{0x66},
|
||||||
|
color.Gray{0x77},
|
||||||
|
color.Gray{0x88},
|
||||||
|
color.Gray{0x99},
|
||||||
|
color.Gray{0xaa},
|
||||||
|
color.Gray{0xbb},
|
||||||
|
color.Gray{0xcc},
|
||||||
|
color.Gray{0xff},
|
||||||
|
}
|
||||||
|
|
||||||
|
var PALETTE_4 = color.Palette{
|
||||||
|
color.Gray{0x00},
|
||||||
|
color.Gray{0x55},
|
||||||
|
color.Gray{0xaa},
|
||||||
|
color.Gray{0xff},
|
||||||
|
}
|
57
main.go
57
main.go
@ -3,11 +3,12 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"image/color"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
imageconverter "github.com/celogeek/go-comic-converter/internal/image-converter"
|
"github.com/celogeek/go-comic-converter/internal/imageconverter"
|
||||||
|
|
||||||
"github.com/celogeek/go-comic-converter/internal/epub"
|
"github.com/celogeek/go-comic-converter/internal/epub"
|
||||||
)
|
)
|
||||||
@ -17,35 +18,36 @@ type Profile struct {
|
|||||||
Description string
|
Description string
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
|
Palette color.Palette
|
||||||
}
|
}
|
||||||
|
|
||||||
var Profiles = []Profile{
|
var Profiles = []Profile{
|
||||||
// Kindle
|
// Kindle
|
||||||
{"K1", "Kindle 1", 600, 670},
|
{"K1", "Kindle 1", 600, 670, imageconverter.PALETTE_4},
|
||||||
{"K11", "Kindle 11", 1072, 1448},
|
{"K11", "Kindle 11", 1072, 1448, imageconverter.PALETTE_16},
|
||||||
{"K2", "Kindle 2", 600, 670},
|
{"K2", "Kindle 2", 600, 670, imageconverter.PALETTE_15},
|
||||||
{"K34", "Kindle Keyboard/Touch", 600, 800},
|
{"K34", "Kindle Keyboard/Touch", 600, 800, imageconverter.PALETTE_16},
|
||||||
{"K578", "Kindle", 600, 800},
|
{"K578", "Kindle", 600, 800, imageconverter.PALETTE_16},
|
||||||
{"KDX", "Kindle DX/DXG", 824, 1000},
|
{"KDX", "Kindle DX/DXG", 824, 1000, imageconverter.PALETTE_16},
|
||||||
{"KPW", "Kindle Paperwhite 1/2", 758, 1024},
|
{"KPW", "Kindle Paperwhite 1/2", 758, 1024, imageconverter.PALETTE_16},
|
||||||
{"KV", "Kindle Paperwhite 3/4/Voyage/Oasis", 1072, 1448},
|
{"KV", "Kindle Paperwhite 3/4/Voyage/Oasis", 1072, 1448, imageconverter.PALETTE_16},
|
||||||
{"KPW5", "Kindle Paperwhite 5/Signature Edition", 1236, 1648},
|
{"KPW5", "Kindle Paperwhite 5/Signature Edition", 1236, 1648, imageconverter.PALETTE_16},
|
||||||
{"KO", "Kindle Oasis 2/3", 1264, 1680},
|
{"KO", "Kindle Oasis 2/3", 1264, 1680, imageconverter.PALETTE_16},
|
||||||
{"KS", "Kindle Scribe", 1860, 2480},
|
{"KS", "Kindle Scribe", 1860, 2480, imageconverter.PALETTE_16},
|
||||||
// Kobo
|
// Kobo
|
||||||
{"KoMT", "Kobo Mini/Touch", 600, 800},
|
{"KoMT", "Kobo Mini/Touch", 600, 800, imageconverter.PALETTE_16},
|
||||||
{"KoG", "Kobo Glo", 768, 1024},
|
{"KoG", "Kobo Glo", 768, 1024, imageconverter.PALETTE_16},
|
||||||
{"KoGHD", "Kobo Glo HD", 1072, 1448},
|
{"KoGHD", "Kobo Glo HD", 1072, 1448, imageconverter.PALETTE_16},
|
||||||
{"KoA", "Kobo Aura", 758, 1024},
|
{"KoA", "Kobo Aura", 758, 1024, imageconverter.PALETTE_16},
|
||||||
{"KoAHD", "Kobo Aura HD", 1080, 1440},
|
{"KoAHD", "Kobo Aura HD", 1080, 1440, imageconverter.PALETTE_16},
|
||||||
{"KoAH2O", "Kobo Aura H2O", 1080, 1430},
|
{"KoAH2O", "Kobo Aura H2O", 1080, 1430, imageconverter.PALETTE_16},
|
||||||
{"KoAO", "Kobo Aura ONE", 1404, 1872},
|
{"KoAO", "Kobo Aura ONE", 1404, 1872, imageconverter.PALETTE_16},
|
||||||
{"KoN", "Kobo Nia", 758, 1024},
|
{"KoN", "Kobo Nia", 758, 1024, imageconverter.PALETTE_16},
|
||||||
{"KoC", "Kobo Clara HD/Kobo Clara 2E", 1072, 1448},
|
{"KoC", "Kobo Clara HD/Kobo Clara 2E", 1072, 1448, imageconverter.PALETTE_16},
|
||||||
{"KoL", "Kobo Libra H2O/Kobo Libra 2", 1264, 1680},
|
{"KoL", "Kobo Libra H2O/Kobo Libra 2", 1264, 1680, imageconverter.PALETTE_16},
|
||||||
{"KoF", "Kobo Forma", 1440, 1920},
|
{"KoF", "Kobo Forma", 1440, 1920, imageconverter.PALETTE_16},
|
||||||
{"KoS", "Kobo Sage", 1440, 1920},
|
{"KoS", "Kobo Sage", 1440, 1920, imageconverter.PALETTE_16},
|
||||||
{"KoE", "Kobo Elipsa", 1404, 1872},
|
{"KoE", "Kobo Elipsa", 1404, 1872, imageconverter.PALETTE_16},
|
||||||
}
|
}
|
||||||
var ProfilesIdx = map[string]int{}
|
var ProfilesIdx = map[string]int{}
|
||||||
|
|
||||||
@ -120,7 +122,7 @@ func main() {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
availableAlgo := make([]string, 0)
|
availableAlgo := make([]string, 0)
|
||||||
for a := range imageconverter.AlgoGray {
|
for a := range imageconverter.ALGO_GRAY {
|
||||||
availableAlgo = append(availableAlgo, a)
|
availableAlgo = append(availableAlgo, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +204,7 @@ 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 {
|
if _, ok := imageconverter.ALGO_GRAY[opt.Algo]; !ok {
|
||||||
fmt.Fprintln(os.Stderr, "algo doesn't exists")
|
fmt.Fprintln(os.Stderr, "algo doesn't exists")
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
@ -222,6 +224,7 @@ func main() {
|
|||||||
Quality: opt.Quality,
|
Quality: opt.Quality,
|
||||||
Crop: !opt.NoCrop,
|
Crop: !opt.NoCrop,
|
||||||
Algo: opt.Algo,
|
Algo: opt.Algo,
|
||||||
|
Palette: profile.Palette,
|
||||||
},
|
},
|
||||||
}).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