do not enlarge smaller images

all width/height are computed based on viewport dimension.
images will enlarge if smaller, and resize to fit if larger.
This commit is contained in:
Celogeek 2023-05-01 14:11:44 +02:00
parent 8b04cbc38f
commit 13103b0eba
Signed by: celogeek
SSH Key Fingerprint: SHA256:njNJLzoLQdbV9PC6ehcruRb0QnEgxABoCYZ+0+aUIYc
4 changed files with 39 additions and 64 deletions

View File

@ -6,6 +6,7 @@ package epubimage
import (
"fmt"
"image"
"strings"
)
type Image struct {
@ -72,24 +73,48 @@ func (i *Image) EPUBImgPath() string {
// center by default.
// align to left or right if it's part of the splitted double page.
func (i *Image) ImgStyle(viewWidth, viewHeight int, align string) string {
marginW, marginH := float64(viewWidth-i.Width)/2, float64(viewHeight-i.Height)/2
relWidth, relHeight := i.RelSize(viewWidth, viewHeight)
marginW, marginH := float64(viewWidth-relWidth)/2, float64(viewHeight-relHeight)/2
style := []string{}
style = append(style, fmt.Sprintf("width:%dpx", relWidth))
style = append(style, fmt.Sprintf("height:%dpx", relHeight))
style = append(style, fmt.Sprintf("top:%.2f%%", marginH*100/float64(viewHeight)))
if align == "" {
switch i.Position {
case "rendition:page-spread-left":
align = "right:0"
style = append(style, "right:0")
case "rendition:page-spread-right":
align = "left:0"
style = append(style, "left:0")
default:
align = fmt.Sprintf("left:%.2f%%", marginW*100/float64(viewWidth))
style = append(style, fmt.Sprintf("left:%.2f%%", marginW*100/float64(viewWidth)))
}
} else {
style = append(style, align)
}
return fmt.Sprintf(
"width:%dpx; height:%dpx; top:%.2f%%; %s;",
i.Width,
i.Height,
marginH*100/float64(viewHeight),
align,
)
return strings.Join(style, "; ")
}
func (i *Image) RelSize(viewWidth, viewHeight int) (relWidth, relHeight int) {
w, h := viewWidth, viewHeight
srcw, srch := i.Width, i.Height
if w <= 0 || h <= 0 || srcw <= 0 || srch <= 0 {
return
}
wratio := float64(srcw) / float64(w)
hratio := float64(srch) / float64(h)
if wratio > hratio {
relWidth = w
relHeight = int(float64(srch)/wratio + 0.5)
} else {
relHeight = h
relWidth = int(float64(srcw)/hratio + 0.5)
}
return
}

View File

@ -1,48 +0,0 @@
package epubimagefilters
import (
"image"
"image/draw"
"github.com/disintegration/gift"
)
// Resize image by keeping aspect ratio.
// This will reduce or enlarge image to fit into the viewWidth and viewHeight.
func Resize(viewWidth, viewHeight int, resampling gift.Resampling) gift.Filter {
return &resizeFilter{
viewWidth, viewHeight, resampling,
}
}
type resizeFilter struct {
viewWidth, viewHeight int
resampling gift.Resampling
}
func (p *resizeFilter) Bounds(srcBounds image.Rectangle) image.Rectangle {
w, h := p.viewWidth, p.viewHeight
srcw, srch := srcBounds.Dx(), srcBounds.Dy()
if w <= 0 || h <= 0 || srcw <= 0 || srch <= 0 {
return image.Rect(0, 0, 0, 0)
}
wratio := float64(srcw) / float64(w)
hratio := float64(srch) / float64(h)
var dstw, dsth int
if wratio > hratio {
dstw = w
dsth = int(float64(srch)/wratio + 0.5)
} else {
dsth = h
dstw = int(float64(srcw)/hratio + 0.5)
}
return image.Rect(0, 0, dstw, dsth)
}
func (p *resizeFilter) Draw(dst draw.Image, src image.Image, options *gift.Options) {
gift.Resize(dst.Bounds().Dx(), dst.Bounds().Dy(), p.resampling).Draw(dst, src, options)
}

View File

@ -202,7 +202,7 @@ func (e *EPUBImageProcessor) transformImage(src image.Image, srcId int) []image.
}
filters = append(filters,
epubimagefilters.Resize(e.Image.View.Width, e.Image.View.Height, gift.LanczosResampling),
gift.ResizeToFit(e.Image.View.Width, e.Image.View.Height, gift.LanczosResampling),
epubimagefilters.Pixel(),
)
@ -234,7 +234,7 @@ func (e *EPUBImageProcessor) transformImage(src image.Image, srcId int) []image.
g := gift.New(splitFilter...)
g.Add(
epubimagefilters.CropSplitDoublePage(b),
epubimagefilters.Resize(e.Image.View.Width, e.Image.View.Height, gift.LanczosResampling),
gift.ResizeToFit(e.Image.View.Width, e.Image.View.Height, gift.LanczosResampling),
)
dst := e.createImage(src, g.Bounds(src.Bounds()))
g.Draw(dst, src)

View File

@ -8,8 +8,6 @@
<meta name="viewport" content="{{ .ViewPort }}"/>
</head>
<body>
<div>
<img src="../{{ .ImagePath }}" alt="{{ .Title }}" style="{{ .ImageStyle }}"/>
</div>
<img src="../{{ .ImagePath }}" alt="{{ .Title }}" style="{{ .ImageStyle }}"/>
</body>
</html>