mirror of
https://github.com/celogeek/go-comic-converter.git
synced 2025-05-25 00:02:37 +02:00
move image transformation to processing
This commit is contained in:
parent
02f86eb55e
commit
6295fefa02
@ -1,70 +0,0 @@
|
||||
package epubimagefilters
|
||||
|
||||
import (
|
||||
"image"
|
||||
|
||||
epubimage "github.com/celogeek/go-comic-converter/v2/internal/epub/image"
|
||||
"github.com/disintegration/gift"
|
||||
)
|
||||
|
||||
// create filter to apply to the source
|
||||
func NewGift(img image.Image, options *epubimage.Options) *gift.GIFT {
|
||||
g := gift.New()
|
||||
g.SetParallelization(false)
|
||||
|
||||
if options.Crop {
|
||||
g.Add(AutoCrop(
|
||||
img,
|
||||
options.CropRatioLeft,
|
||||
options.CropRatioUp,
|
||||
options.CropRatioRight,
|
||||
options.CropRatioBottom,
|
||||
))
|
||||
}
|
||||
if options.AutoRotate && img.Bounds().Dx() > img.Bounds().Dy() {
|
||||
g.Add(gift.Rotate90())
|
||||
}
|
||||
|
||||
if options.Contrast != 0 {
|
||||
g.Add(gift.Contrast(float32(options.Contrast)))
|
||||
}
|
||||
|
||||
if options.Brightness != 0 {
|
||||
g.Add(gift.Brightness(float32(options.Brightness)))
|
||||
}
|
||||
|
||||
g.Add(
|
||||
Resize(options.ViewWidth, options.ViewHeight, gift.LanczosResampling),
|
||||
Pixel(),
|
||||
)
|
||||
return g
|
||||
}
|
||||
|
||||
// create filters to cut image into 2 equal pieces
|
||||
func NewGiftSplitDoublePage(options *epubimage.Options) []*gift.GIFT {
|
||||
gifts := make([]*gift.GIFT, 2)
|
||||
|
||||
gifts[0] = gift.New(
|
||||
CropSplitDoublePage(options.Manga),
|
||||
)
|
||||
|
||||
gifts[1] = gift.New(
|
||||
CropSplitDoublePage(!options.Manga),
|
||||
)
|
||||
|
||||
for _, g := range gifts {
|
||||
g.SetParallelization(false)
|
||||
if options.Contrast != 0 {
|
||||
g.Add(gift.Contrast(float32(options.Contrast)))
|
||||
}
|
||||
if options.Brightness != 0 {
|
||||
g.Add(gift.Brightness(float32(options.Brightness)))
|
||||
}
|
||||
|
||||
g.Add(
|
||||
Resize(options.ViewWidth, options.ViewHeight, gift.LanczosResampling),
|
||||
)
|
||||
}
|
||||
|
||||
return gifts
|
||||
}
|
@ -61,7 +61,7 @@ func LoadImages(o *Options) ([]*epubimage.Image, error) {
|
||||
})
|
||||
wg := &sync.WaitGroup{}
|
||||
|
||||
for i := 0; i < o.Workers; i++ {
|
||||
for i := 0; i < o.WorkersRatio(50); i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
@ -69,52 +69,23 @@ func LoadImages(o *Options) ([]*epubimage.Image, error) {
|
||||
for img := range imageInput {
|
||||
src := img.Image
|
||||
|
||||
g := epubimagefilters.NewGift(src, o.Image)
|
||||
// Convert image
|
||||
dst := image.NewGray(g.Bounds(src.Bounds()))
|
||||
g.Draw(dst, src)
|
||||
for part, dst := range TransformImage(src, img.Id, o.Image) {
|
||||
var raw image.Image
|
||||
if img.Id == 0 && part == 0 {
|
||||
raw = dst
|
||||
}
|
||||
|
||||
var raw image.Image
|
||||
if img.Id == 0 {
|
||||
raw = dst
|
||||
}
|
||||
|
||||
imageOutput <- &epubimage.Image{
|
||||
Id: img.Id,
|
||||
Part: 0,
|
||||
Raw: raw,
|
||||
Data: epubimagedata.New(img.Id, 0, dst, o.Image.Quality),
|
||||
Width: dst.Bounds().Dx(),
|
||||
Height: dst.Bounds().Dy(),
|
||||
IsCover: img.Id == 0,
|
||||
DoublePage: src.Bounds().Dx() > src.Bounds().Dy(),
|
||||
Path: img.Path,
|
||||
Name: img.Name,
|
||||
}
|
||||
|
||||
// Auto split double page
|
||||
// Except for cover
|
||||
// Only if the src image have width > height and is bigger than the view
|
||||
if (!o.Image.HasCover || img.Id > 0) &&
|
||||
o.Image.AutoSplitDoublePage &&
|
||||
src.Bounds().Dx() > src.Bounds().Dy() {
|
||||
gifts := epubimagefilters.NewGiftSplitDoublePage(o.Image)
|
||||
for i, g := range gifts {
|
||||
part := i + 1
|
||||
dst := image.NewGray(g.Bounds(src.Bounds()))
|
||||
g.Draw(dst, src)
|
||||
|
||||
imageOutput <- &epubimage.Image{
|
||||
Id: img.Id,
|
||||
Part: part,
|
||||
Data: epubimagedata.New(img.Id, part, dst, o.Image.Quality),
|
||||
Width: dst.Bounds().Dx(),
|
||||
Height: dst.Bounds().Dy(),
|
||||
IsCover: false,
|
||||
DoublePage: false,
|
||||
Path: img.Path,
|
||||
Name: img.Name,
|
||||
}
|
||||
imageOutput <- &epubimage.Image{
|
||||
Id: img.Id,
|
||||
Part: part,
|
||||
Raw: raw,
|
||||
Data: epubimagedata.New(img.Id, part, dst, o.Image.Quality),
|
||||
Width: dst.Bounds().Dx(),
|
||||
Height: dst.Bounds().Dy(),
|
||||
IsCover: img.Id == 0 && part == 0,
|
||||
DoublePage: part == 0 && src.Bounds().Dx() > src.Bounds().Dy(),
|
||||
Path: img.Path,
|
||||
Name: img.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,3 +124,80 @@ func LoadCoverTitleData(img *epubimage.Image, title string, quality int) *epubim
|
||||
|
||||
return epubimagedata.NewRaw("OEBPS/Images/title.jpg", dst, quality)
|
||||
}
|
||||
|
||||
// transform image into 1 or 3 images
|
||||
// only doublepage with autosplit has 3 versions
|
||||
func TransformImage(src image.Image, srcId int, o *epubimage.Options) []image.Image {
|
||||
var filters, splitFilter []gift.Filter
|
||||
var images []image.Image
|
||||
|
||||
if o.Crop {
|
||||
f := epubimagefilters.AutoCrop(
|
||||
src,
|
||||
o.CropRatioLeft,
|
||||
o.CropRatioUp,
|
||||
o.CropRatioRight,
|
||||
o.CropRatioBottom,
|
||||
)
|
||||
filters = append(filters, f)
|
||||
splitFilter = append(splitFilter, f)
|
||||
}
|
||||
|
||||
if o.AutoRotate && src.Bounds().Dx() > src.Bounds().Dy() {
|
||||
filters = append(filters, gift.Rotate90())
|
||||
}
|
||||
|
||||
if o.Contrast != 0 {
|
||||
f := gift.Contrast(float32(o.Contrast))
|
||||
filters = append(filters, f)
|
||||
splitFilter = append(splitFilter, f)
|
||||
}
|
||||
|
||||
if o.Brightness != 0 {
|
||||
f := gift.Brightness(float32(o.Brightness))
|
||||
filters = append(filters, f)
|
||||
splitFilter = append(splitFilter, f)
|
||||
}
|
||||
|
||||
filters = append(filters,
|
||||
epubimagefilters.Resize(o.ViewWidth, o.ViewHeight, gift.LanczosResampling),
|
||||
epubimagefilters.Pixel(),
|
||||
)
|
||||
|
||||
// convert
|
||||
{
|
||||
g := gift.New(filters...)
|
||||
dst := image.NewGray(g.Bounds(src.Bounds()))
|
||||
g.Draw(dst, src)
|
||||
images = append(images, dst)
|
||||
}
|
||||
|
||||
// auto split off
|
||||
if !o.AutoSplitDoublePage {
|
||||
return images
|
||||
}
|
||||
|
||||
// portrait, no need to split
|
||||
if src.Bounds().Dx() <= src.Bounds().Dy() {
|
||||
return images
|
||||
}
|
||||
|
||||
// cover
|
||||
if o.HasCover && srcId == 0 {
|
||||
return images
|
||||
}
|
||||
|
||||
// convert double page
|
||||
for _, b := range []bool{o.Manga, !o.Manga} {
|
||||
g := gift.New(splitFilter...)
|
||||
g.Add(
|
||||
epubimagefilters.CropSplitDoublePage(b),
|
||||
epubimagefilters.Resize(o.ViewWidth, o.ViewHeight, gift.LanczosResampling),
|
||||
)
|
||||
dst := image.NewGray(g.Bounds(src.Bounds()))
|
||||
g.Draw(dst, src)
|
||||
images = append(images, dst)
|
||||
}
|
||||
|
||||
return images
|
||||
}
|
||||
|
@ -43,6 +43,14 @@ type Options struct {
|
||||
|
||||
var errNoImagesFound = errors.New("no images found")
|
||||
|
||||
func (o *Options) WorkersRatio(pct int) (nbWorkers int) {
|
||||
nbWorkers = o.Workers * pct / 100
|
||||
if nbWorkers < 1 {
|
||||
nbWorkers = 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (o *Options) Load() (totalImages int, output chan *tasks, err error) {
|
||||
fi, err := os.Stat(o.Input)
|
||||
if err != nil {
|
||||
@ -112,8 +120,8 @@ func (o *Options) loadDir() (totalImages int, output chan *tasks, err error) {
|
||||
// read in parallel and get an image
|
||||
output = make(chan *tasks, o.Workers)
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(o.Workers)
|
||||
for j := 0; j < o.Workers; j++ {
|
||||
for j := 0; j < o.WorkersRatio(50); j++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for job := range jobs {
|
||||
@ -204,8 +212,8 @@ func (o *Options) loadCbz() (totalImages int, output chan *tasks, err error) {
|
||||
|
||||
output = make(chan *tasks, o.Workers)
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(o.Workers)
|
||||
for j := 0; j < o.Workers; j++ {
|
||||
for j := 0; j < o.WorkersRatio(50); j++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for job := range jobs {
|
||||
@ -323,8 +331,8 @@ func (o *Options) loadCbr() (totalImages int, output chan *tasks, err error) {
|
||||
// send file to the queue
|
||||
output = make(chan *tasks, o.Workers)
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(o.Workers)
|
||||
for j := 0; j < o.Workers; j++ {
|
||||
for j := 0; j < o.WorkersRatio(50); j++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for job := range jobs {
|
||||
|
Loading…
x
Reference in New Issue
Block a user