Merge branch 'alpha_channel_fix'
Colors in image.RGBA, image.RGBA64 and generic types with alpha channel should now resize correctly. There's a small performance hit for these image types even if they don't use alpha channels though. Fixes bug #26.
This commit is contained in:
commit
f2d1b73023
59
converter.go
59
converter.go
|
@ -64,6 +64,17 @@ func resizeGeneric(in image.Image, out *image.NRGBA64, scale float64, coeffs []i
|
||||||
xi = maxX
|
xi = maxX
|
||||||
}
|
}
|
||||||
r, g, b, a := in.At(xi+in.Bounds().Min.X, x+in.Bounds().Min.Y).RGBA()
|
r, g, b, a := in.At(xi+in.Bounds().Min.X, x+in.Bounds().Min.Y).RGBA()
|
||||||
|
|
||||||
|
// reverse alpha-premultiplication.
|
||||||
|
if a != 0 {
|
||||||
|
r *= 0xffff
|
||||||
|
r /= a
|
||||||
|
g *= 0xffff
|
||||||
|
g /= a
|
||||||
|
b *= 0xffff
|
||||||
|
b /= a
|
||||||
|
}
|
||||||
|
|
||||||
rgba[0] += int64(coeff) * int64(r)
|
rgba[0] += int64(coeff) * int64(r)
|
||||||
rgba[1] += int64(coeff) * int64(g)
|
rgba[1] += int64(coeff) * int64(g)
|
||||||
rgba[2] += int64(coeff) * int64(b)
|
rgba[2] += int64(coeff) * int64(b)
|
||||||
|
@ -112,10 +123,26 @@ func resizeRGBA(in *image.RGBA, out *image.NRGBA, scale float64, coeffs []int16,
|
||||||
default:
|
default:
|
||||||
xi = 0
|
xi = 0
|
||||||
}
|
}
|
||||||
rgba[0] += int32(coeff) * int32(row[xi+0])
|
|
||||||
rgba[1] += int32(coeff) * int32(row[xi+1])
|
r := uint32(row[xi+0])
|
||||||
rgba[2] += int32(coeff) * int32(row[xi+2])
|
g := uint32(row[xi+1])
|
||||||
rgba[3] += int32(coeff) * int32(row[xi+3])
|
b := uint32(row[xi+2])
|
||||||
|
a := uint32(row[xi+3])
|
||||||
|
|
||||||
|
// reverse alpha-premultiplication.
|
||||||
|
if a != 0 {
|
||||||
|
r *= 0xffff
|
||||||
|
r /= a
|
||||||
|
g *= 0xffff
|
||||||
|
g /= a
|
||||||
|
b *= 0xffff
|
||||||
|
b /= a
|
||||||
|
}
|
||||||
|
|
||||||
|
rgba[0] += int32(coeff) * int32(r)
|
||||||
|
rgba[1] += int32(coeff) * int32(g)
|
||||||
|
rgba[2] += int32(coeff) * int32(b)
|
||||||
|
rgba[3] += int32(coeff) * int32(a)
|
||||||
sum += int32(coeff)
|
sum += int32(coeff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,10 +219,26 @@ func resizeRGBA64(in *image.RGBA64, out *image.NRGBA64, scale float64, coeffs []
|
||||||
default:
|
default:
|
||||||
xi = 0
|
xi = 0
|
||||||
}
|
}
|
||||||
rgba[0] += int64(coeff) * int64(uint16(row[xi+0])<<8|uint16(row[xi+1]))
|
|
||||||
rgba[1] += int64(coeff) * int64(uint16(row[xi+2])<<8|uint16(row[xi+3]))
|
r := uint32(uint16(row[xi+0])<<8 | uint16(row[xi+1]))
|
||||||
rgba[2] += int64(coeff) * int64(uint16(row[xi+4])<<8|uint16(row[xi+5]))
|
g := uint32(uint16(row[xi+2])<<8 | uint16(row[xi+3]))
|
||||||
rgba[3] += int64(coeff) * int64(uint16(row[xi+6])<<8|uint16(row[xi+7]))
|
b := uint32(uint16(row[xi+4])<<8 | uint16(row[xi+5]))
|
||||||
|
a := uint32(uint16(row[xi+6])<<8 | uint16(row[xi+7]))
|
||||||
|
|
||||||
|
// reverse alpha-premultiplication.
|
||||||
|
if a != 0 {
|
||||||
|
r *= 0xffff
|
||||||
|
r /= a
|
||||||
|
g *= 0xffff
|
||||||
|
g /= a
|
||||||
|
b *= 0xffff
|
||||||
|
b /= a
|
||||||
|
}
|
||||||
|
|
||||||
|
rgba[0] += int64(coeff) * int64(r)
|
||||||
|
rgba[1] += int64(coeff) * int64(g)
|
||||||
|
rgba[2] += int64(coeff) * int64(b)
|
||||||
|
rgba[3] += int64(coeff) * int64(a)
|
||||||
sum += int64(coeff)
|
sum += int64(coeff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,21 @@ func Test_PixelCoordinates(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_ResizeWithPremultipliedAlpha(t *testing.T) {
|
||||||
|
img := image.NewRGBA(image.Rect(0, 0, 1, 4))
|
||||||
|
for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ {
|
||||||
|
// 0x80 = 0.5 * 0xFF.
|
||||||
|
img.SetRGBA(0, y, color.RGBA{0x80, 0x80, 0x80, 0x80})
|
||||||
|
}
|
||||||
|
|
||||||
|
out := Resize(1, 2, img, MitchellNetravali)
|
||||||
|
|
||||||
|
outputColor := out.At(0, 0).(color.NRGBA)
|
||||||
|
if outputColor.R != 0xFF {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Use a small image size for benchmarks. We don't want memory performance
|
// Use a small image size for benchmarks. We don't want memory performance
|
||||||
// to affect the benchmark results.
|
// to affect the benchmark results.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user