2022-12-26 16:21:31 +01:00

155 lines
2.8 KiB
Go

package comicconverter
import (
"bytes"
"image"
"image/color"
"image/jpeg"
"os"
"github.com/vincent-petithory/dataurl"
"golang.org/x/image/draw"
)
func Load(file string) *image.Gray {
f, err := os.Open(file)
if err != nil {
panic(err)
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
panic(err)
}
switch imgt := img.(type) {
case *image.Gray:
return imgt
default:
newImg := image.NewGray(img.Bounds())
draw.Draw(newImg, newImg.Bounds(), img, image.Point{}, draw.Src)
return newImg
}
}
func isBlank(c color.Color) bool {
r, g, b, _ := c.RGBA()
return r > 60000 && g > 60000 && b > 60000
}
func CropMarging(img *image.Gray) *image.Gray {
imgArea := img.Bounds()
LEFT:
for x := imgArea.Min.X; x < imgArea.Max.X; x++ {
for y := imgArea.Min.Y; y < imgArea.Max.Y; y++ {
if !isBlank(img.At(x, y)) {
break LEFT
}
}
imgArea.Min.X++
}
UP:
for y := imgArea.Min.Y; y < imgArea.Max.Y; y++ {
for x := imgArea.Min.X; x < imgArea.Max.X; x++ {
if !isBlank(img.At(x, y)) {
break UP
}
}
imgArea.Min.Y++
}
RIGHT:
for x := imgArea.Max.X - 1; x >= imgArea.Min.X; x-- {
for y := imgArea.Min.Y; y < imgArea.Max.Y; y++ {
if !isBlank(img.At(x, y)) {
break RIGHT
}
}
imgArea.Max.X--
}
BOTTOM:
for y := imgArea.Max.Y - 1; y >= imgArea.Min.Y; y-- {
for x := imgArea.Min.X; x < imgArea.Max.X; x++ {
if !isBlank(img.At(x, y)) {
break BOTTOM
}
}
imgArea.Max.Y--
}
return img.SubImage(imgArea).(*image.Gray)
}
func Resize(img *image.Gray, w, h int) *image.Gray {
dim := img.Bounds()
origWidth := dim.Dx()
origHeight := dim.Dy()
if origWidth == 0 || origHeight == 0 {
newImg := image.NewGray(image.Rectangle{
image.Point{0, 0},
image.Point{w, h},
})
draw.Draw(newImg, newImg.Bounds(), image.NewUniform(color.White), newImg.Bounds().Min, draw.Src)
return newImg
}
width, height := origWidth*h/origHeight, origHeight*w/origWidth
if width > w {
width = w
}
if height > h {
height = h
}
newImg := image.NewGray(image.Rectangle{
Min: image.Point{0, 0},
Max: image.Point{width, height},
})
draw.BiLinear.Scale(newImg, newImg.Bounds(), img, img.Bounds(), draw.Src, nil)
return newImg
}
func Get(img *image.Gray, quality int) string {
b := bytes.NewBuffer([]byte{})
err := jpeg.Encode(b, img, &jpeg.Options{Quality: quality})
if err != nil {
panic(err)
}
du := dataurl.EncodeBytes(b.Bytes())
return du
}
func Save(img *image.Gray, output string, quality int) {
o, err := os.Create(output)
if err != nil {
panic(err)
}
defer o.Close()
if quality == 0 {
quality = 75
}
err = jpeg.Encode(o, img, &jpeg.Options{Quality: quality})
if err != nil {
panic(err)
}
}
func Convert(path string, crop bool, w, h int, quality int) string {
img := Load(path)
if crop {
img = CropMarging(img)
}
img = Resize(img, w, h)
return Get(img, quality)
}