graphics: More precise enlarging

Before this change, enlarging a 1px image with x4095 scale was not
accurate and edges were missing. This change fixes this issue.

Updates #611
This commit is contained in:
Hajime Hoshi 2019-07-31 22:01:45 +09:00
parent ab0a6f4ff7
commit e434869dd7
2 changed files with 15 additions and 4 deletions

View File

@ -961,12 +961,15 @@ loop:
src.ReplacePixels(pix) src.ReplacePixels(pix)
_, dh := dst.Size() _, dh := dst.Size()
for i := 32; i < dh; i += 32 { for i := 0; i < dh; {
dst.Clear() dst.Clear()
op := &DrawImageOptions{} op := &DrawImageOptions{}
op.GeoM.Scale(1, float64(i)/float64(h)) op.GeoM.Scale(1, float64(i)/float64(h))
dst.DrawImage(src.SubImage(image.Rect(0, 0, w, h)).(*Image), op) dst.DrawImage(src.SubImage(image.Rect(0, 0, w, h)).(*Image), op)
for j := -2; j <= 2; j++ { for j := -1; j <= 1; j++ {
if i+j < 0 {
continue
}
got := dst.At(0, i+j).(color.RGBA) got := dst.At(0, i+j).(color.RGBA)
want := color.RGBA{} want := color.RGBA{}
if j < 0 { if j < 0 {
@ -977,6 +980,14 @@ loop:
continue loop continue loop
} }
} }
switch i % 32 {
case 31, 0:
i++
case 1:
i += 32 - 2
default:
panic("not reached")
}
} }
} }
} }

View File

@ -161,8 +161,8 @@ func (m *mipmap) mipmapLevel(geom *GeoM, width, height int, filter driver.Filter
} }
// Use 'negative' mipmap to render edges correctly (#611, #907). // Use 'negative' mipmap to render edges correctly (#611, #907).
// It looks like 256 is the enlargement factor that causes edge missings to pass the test TestImageStretch. // It looks like 128 is the enlargement factor that causes edge missings to pass the test TestImageStretch.
const tooBigScale = 256 const tooBigScale = 128
if sx, sy := geomScaleSize(geom); sx >= tooBigScale || sy >= tooBigScale { if sx, sy := geomScaleSize(geom); sx >= tooBigScale || sy >= tooBigScale {
// If the filter is not nearest, the target needs to be rendered with gradiation. Don't use mipmaps. // If the filter is not nearest, the target needs to be rendered with gradiation. Don't use mipmaps.
if filter != driver.FilterNearest { if filter != driver.FilterNearest {