diff --git a/internal/epub/epub.go b/internal/epub/epub.go index 3c78fd6..9f8eb9f 100644 --- a/internal/epub/epub.go +++ b/internal/epub/epub.go @@ -252,7 +252,7 @@ func (e *ePub) Write() error { return err } } - if err := wz.WriteImage(e.createTitleImageData(title, part.Cover, i+1, totalParts)); err != nil { + if err := wz.WriteImage(e.coverTitleImageData(title, part.Cover, i+1, totalParts)); err != nil { return err } diff --git a/internal/epub/epub_image_processing.go b/internal/epub/epub_image_processing.go index 207f4d8..fc56610 100644 --- a/internal/epub/epub_image_processing.go +++ b/internal/epub/epub_image_processing.go @@ -6,7 +6,6 @@ import ( "fmt" "image" "image/color" - "image/draw" _ "image/jpeg" _ "image/png" "io" @@ -17,17 +16,14 @@ import ( "strings" "sync" + epubfilters "github.com/celogeek/go-comic-converter/v2/internal/epub/filters" epubimage "github.com/celogeek/go-comic-converter/v2/internal/epub/image" epubimagedata "github.com/celogeek/go-comic-converter/v2/internal/epub/imagedata" "github.com/celogeek/go-comic-converter/v2/internal/sortpath" "github.com/disintegration/gift" - "github.com/golang/freetype" - "github.com/golang/freetype/truetype" "github.com/nwaples/rardecode" pdfimage "github.com/raff/pdfreader/image" "github.com/raff/pdfreader/pdfread" - "golang.org/x/image/font" - "golang.org/x/image/font/gofont/gomonobold" "golang.org/x/image/tiff" _ "golang.org/x/image/webp" ) @@ -458,62 +454,11 @@ func loadPdf(input string) (int, chan *imageTask, error) { return nbPages, output, nil } -func (e *ePub) createTitleImageData(title string, img *epubimage.Image, currentPart, totalPart int) *epubimagedata.ImageData { +func (e *ePub) coverTitleImageData(title string, img *epubimage.Image, currentPart, totalPart int) *epubimagedata.ImageData { // Create a blur version of the cover - g := gift.New(gift.GaussianBlur(8)) + g := gift.New(epubfilters.CoverTitle(title)) dst := image.NewGray(g.Bounds(img.Raw.Bounds())) g.Draw(dst, img.Raw) - // Calculate size of title - f, _ := truetype.Parse(gomonobold.TTF) - borderSize := 4 - var fontSize, textWidth, textHeight int - for fontSize = 64; fontSize >= 12; fontSize -= 1 { - face := truetype.NewFace(f, &truetype.Options{Size: float64(fontSize), DPI: 72}) - textWidth = font.MeasureString(face, title).Ceil() - textHeight = face.Metrics().Ascent.Ceil() + face.Metrics().Descent.Ceil() - if textWidth+2*borderSize < img.Width && 3*textHeight+2*borderSize < img.Height { - break - } - } - - // Draw rectangle in the middle of the image - textPosStart := img.Height/2 - textHeight/2 - textPosEnd := img.Height/2 + textHeight/2 - marginSize := fontSize - borderArea := image.Rect(0, textPosStart-borderSize-marginSize, img.Width, textPosEnd+borderSize+marginSize) - textArea := image.Rect(borderSize, textPosStart-marginSize, img.Width-borderSize, textPosEnd+marginSize) - - draw.Draw( - dst, - borderArea, - image.Black, - image.Point{}, - draw.Over, - ) - - draw.Draw( - dst, - textArea, - image.White, - image.Point{}, - draw.Over, - ) - - // Draw text - c := freetype.NewContext() - c.SetDPI(72) - c.SetFontSize(float64(fontSize)) - c.SetFont(f) - c.SetClip(textArea) - c.SetDst(dst) - c.SetSrc(image.Black) - - textLeft := img.Width/2 - textWidth/2 - if textLeft < borderSize { - textLeft = borderSize - } - c.DrawString(title, freetype.Pt(textLeft, img.Height/2+textHeight/4)) - return epubimagedata.NewRaw("OEBPS/Images/title.jpg", dst, e.Image.Quality) } diff --git a/internal/epub/filters/epub_filters_cover_title.go b/internal/epub/filters/epub_filters_cover_title.go new file mode 100644 index 0000000..51ce8b9 --- /dev/null +++ b/internal/epub/filters/epub_filters_cover_title.go @@ -0,0 +1,83 @@ +package epubfilters + +import ( + "image" + "image/draw" + + "github.com/disintegration/gift" + "github.com/golang/freetype" + "github.com/golang/freetype/truetype" + "golang.org/x/image/font" + "golang.org/x/image/font/gofont/gomonobold" +) + +func CoverTitle(title string) gift.Filter { + return &coverTitle{title} +} + +type coverTitle struct { + title string +} + +func (p *coverTitle) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { + return srcBounds +} + +func (p *coverTitle) Draw(dst draw.Image, src image.Image, options *gift.Options) { + // Create a blur version of the cover + g := gift.New(gift.GaussianBlur(4)) + g.Draw(dst, src) + + srcWidth, srcHeight := src.Bounds().Dx(), src.Bounds().Dy() + + // Calculate size of title + f, _ := truetype.Parse(gomonobold.TTF) + borderSize := 4 + var fontSize, textWidth, textHeight int + for fontSize = 64; fontSize >= 12; fontSize -= 1 { + face := truetype.NewFace(f, &truetype.Options{Size: float64(fontSize), DPI: 72}) + textWidth = font.MeasureString(face, p.title).Ceil() + textHeight = face.Metrics().Ascent.Ceil() + face.Metrics().Descent.Ceil() + if textWidth+2*borderSize < srcWidth && 3*textHeight+2*borderSize < srcHeight { + break + } + } + + // Draw rectangle in the middle of the image + textPosStart := srcHeight/2 - textHeight/2 + textPosEnd := srcHeight/2 + textHeight/2 + marginSize := fontSize + borderArea := image.Rect(0, textPosStart-borderSize-marginSize, srcWidth, textPosEnd+borderSize+marginSize) + textArea := image.Rect(borderSize, textPosStart-marginSize, srcWidth-borderSize, textPosEnd+marginSize) + + draw.Draw( + dst, + borderArea, + image.Black, + image.Point{}, + draw.Over, + ) + + draw.Draw( + dst, + textArea, + image.White, + image.Point{}, + draw.Over, + ) + + // Draw text + c := freetype.NewContext() + c.SetDPI(72) + c.SetFontSize(float64(fontSize)) + c.SetFont(f) + c.SetClip(textArea) + c.SetDst(dst) + c.SetSrc(image.Black) + + textLeft := srcWidth/2 - textWidth/2 + if textLeft < borderSize { + textLeft = borderSize + } + c.DrawString(p.title, freetype.Pt(textLeft, srcHeight/2+textHeight/4)) +}