fixed image drawing, added some interpolation
This commit is contained in:
parent
a0a1adef12
commit
e3bb07a09c
4 changed files with 99 additions and 59 deletions
70
backend/software/color.go
Normal file
70
backend/software/color.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package softwarebackend
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"math"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mix(src, dest color.Color) color.RGBA {
|
||||||
|
ir1, ig1, ib1, ia1 := src.RGBA()
|
||||||
|
r1 := float64(ir1) / 65535.0
|
||||||
|
g1 := float64(ig1) / 65535.0
|
||||||
|
b1 := float64(ib1) / 65535.0
|
||||||
|
a1 := float64(ia1) / 65535.0
|
||||||
|
|
||||||
|
ir2, ig2, ib2, _ := dest.RGBA()
|
||||||
|
r2 := float64(ir2) / 65535.0
|
||||||
|
g2 := float64(ig2) / 65535.0
|
||||||
|
b2 := float64(ib2) / 65535.0
|
||||||
|
|
||||||
|
r := (r1-r2)*a1 + r2
|
||||||
|
g := (g1-g2)*a1 + g2
|
||||||
|
b := (b1-b2)*a1 + b2
|
||||||
|
|
||||||
|
return color.RGBA{
|
||||||
|
R: uint8(math.Round(r * 255.0)),
|
||||||
|
G: uint8(math.Round(g * 255.0)),
|
||||||
|
B: uint8(math.Round(b * 255.0)),
|
||||||
|
A: 255,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func alphaColor(col color.Color, alpha color.Alpha) color.RGBA {
|
||||||
|
ir, ig, ib, _ := col.RGBA()
|
||||||
|
a2 := float64(alpha.A) / 255.0
|
||||||
|
r := float64(ir) * a2 / 65535.0
|
||||||
|
g := float64(ig) * a2 / 65535.0
|
||||||
|
b := float64(ib) * a2 / 65535.0
|
||||||
|
return color.RGBA{
|
||||||
|
R: uint8(r * 255.0),
|
||||||
|
G: uint8(g * 255.0),
|
||||||
|
B: uint8(b * 255.0),
|
||||||
|
A: 255,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func lerp(col1, col2 color.Color, ratio float64) color.RGBA {
|
||||||
|
ir1, ig1, ib1, ia1 := col1.RGBA()
|
||||||
|
r1 := float64(ir1) / 65535.0
|
||||||
|
g1 := float64(ig1) / 65535.0
|
||||||
|
b1 := float64(ib1) / 65535.0
|
||||||
|
a1 := float64(ia1) / 65535.0
|
||||||
|
|
||||||
|
ir2, ig2, ib2, ia2 := col2.RGBA()
|
||||||
|
r2 := float64(ir2) / 65535.0
|
||||||
|
g2 := float64(ig2) / 65535.0
|
||||||
|
b2 := float64(ib2) / 65535.0
|
||||||
|
a2 := float64(ia2) / 65535.0
|
||||||
|
|
||||||
|
r := (r1-r2)*ratio + r2
|
||||||
|
g := (g1-g2)*ratio + g2
|
||||||
|
b := (b1-b2)*ratio + b2
|
||||||
|
a := (a1-a2)*ratio + a2
|
||||||
|
|
||||||
|
return color.RGBA{
|
||||||
|
R: uint8(math.Round(r * 255.0)),
|
||||||
|
G: uint8(math.Round(g * 255.0)),
|
||||||
|
B: uint8(math.Round(b * 255.0)),
|
||||||
|
A: uint8(math.Round(a * 255.0)),
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ package softwarebackend
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"math"
|
|
||||||
|
|
||||||
"github.com/tfriedel6/canvas/backend/backendbase"
|
"github.com/tfriedel6/canvas/backend/backendbase"
|
||||||
)
|
)
|
||||||
|
@ -39,50 +38,12 @@ func (b *SoftwareBackend) Fill(style *backendbase.FillStyle, pts [][2]float64) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func mix(src, dest color.Color) color.RGBA {
|
|
||||||
ir1, ig1, ib1, ia1 := src.RGBA()
|
|
||||||
r1 := float64(ir1) / 65535.0
|
|
||||||
g1 := float64(ig1) / 65535.0
|
|
||||||
b1 := float64(ib1) / 65535.0
|
|
||||||
a1 := float64(ia1) / 65535.0
|
|
||||||
|
|
||||||
ir2, ig2, ib2, _ := dest.RGBA()
|
|
||||||
r2 := float64(ir2) / 65535.0
|
|
||||||
g2 := float64(ig2) / 65535.0
|
|
||||||
b2 := float64(ib2) / 65535.0
|
|
||||||
|
|
||||||
r := (r1-r2)*a1 + r2
|
|
||||||
g := (g1-g2)*a1 + g2
|
|
||||||
b := (b1-b2)*a1 + b2
|
|
||||||
|
|
||||||
return color.RGBA{
|
|
||||||
R: uint8(math.Round(r * 255.0)),
|
|
||||||
G: uint8(math.Round(g * 255.0)),
|
|
||||||
B: uint8(math.Round(b * 255.0)),
|
|
||||||
A: 255,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func alphaColor(col color.Color, alpha color.Alpha) color.RGBA {
|
|
||||||
ir, ig, ib, _ := col.RGBA()
|
|
||||||
a2 := float64(alpha.A) / 255.0
|
|
||||||
r := float64(ir) * a2 / 65535.0
|
|
||||||
g := float64(ig) * a2 / 65535.0
|
|
||||||
b := float64(ib) * a2 / 65535.0
|
|
||||||
return color.RGBA{
|
|
||||||
R: uint8(r * 255.0),
|
|
||||||
G: uint8(g * 255.0),
|
|
||||||
B: uint8(b * 255.0),
|
|
||||||
A: 255,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *SoftwareBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Alpha, pts [4][2]float64) {
|
func (b *SoftwareBackend) FillImageMask(style *backendbase.FillStyle, mask *image.Alpha, pts [4][2]float64) {
|
||||||
mw := float64(mask.Bounds().Dx())
|
mw := float64(mask.Bounds().Dx())
|
||||||
mh := float64(mask.Bounds().Dy())
|
mh := float64(mask.Bounds().Dy())
|
||||||
b.fillQuad(pts, func(x, y int, sx2, sy2 float64) {
|
b.fillQuad(pts, func(x, y int, sx2, sy2 float64) {
|
||||||
sxi := int(mw*sx2 + 0.5)
|
sxi := int(mw * sx2)
|
||||||
syi := int(mh*sy2 + 0.5)
|
syi := int(mh * sy2)
|
||||||
a := mask.AlphaAt(sxi, syi)
|
a := mask.AlphaAt(sxi, syi)
|
||||||
if a.A == 0 {
|
if a.A == 0 {
|
||||||
return
|
return
|
||||||
|
|
|
@ -2,6 +2,7 @@ package softwarebackend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
|
"math"
|
||||||
|
|
||||||
"github.com/tfriedel6/canvas/backend/backendbase"
|
"github.com/tfriedel6/canvas/backend/backendbase"
|
||||||
)
|
)
|
||||||
|
@ -21,9 +22,19 @@ func (b *SoftwareBackend) DrawImage(dimg backendbase.Image, sx, sy, sw, sh float
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.fillQuad(pts, func(x, y int, sx2, sy2 float64) {
|
b.fillQuad(pts, func(x, y int, sx2, sy2 float64) {
|
||||||
sxi := int(sx + sw*sx2 + 0.5)
|
imgx := sx + sw*sx2
|
||||||
syi := int(sy + sh*sy2 + 0.5)
|
imgy := sy + sh*sy2
|
||||||
b.Image.Set(x, y, simg.img.At(sxi, syi))
|
imgxf := math.Floor(imgx)
|
||||||
|
imgyf := math.Floor(imgy)
|
||||||
|
rx := imgx - imgxf
|
||||||
|
ry := imgy - imgyf
|
||||||
|
ca := simg.img.At(int(imgxf), int(imgyf))
|
||||||
|
cb := simg.img.At(int(imgxf+1), int(imgyf))
|
||||||
|
cc := simg.img.At(int(imgxf), int(imgyf+1))
|
||||||
|
cd := simg.img.At(int(imgxf+1), int(imgyf+1))
|
||||||
|
ctop := lerp(ca, cb, rx)
|
||||||
|
cbtm := lerp(cc, cd, rx)
|
||||||
|
b.Image.Set(x, y, lerp(ctop, cbtm, ry))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,27 +134,25 @@ func (b *SoftwareBackend) fillQuad(quad [4][2]float64, fn func(x, y int, sx, sy
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
v0 := [2]float64{float64(l) - quad[0][0], float64(y) - quad[0][1]}
|
sfy := float64(y) + 0.5 - quad[0][1]
|
||||||
sx0 := topv[0]*v0[0] + topv[1]*v0[1]
|
|
||||||
sy0 := leftv[0]*v0[0] + leftv[1]*v0[1]
|
|
||||||
|
|
||||||
v1 := [2]float64{float64(r) - quad[0][0], float64(y) - quad[0][1]}
|
|
||||||
sx1 := topv[0]*v1[0] + topv[1]*v1[1]
|
|
||||||
sy1 := leftv[0]*v1[0] + leftv[1]*v1[1]
|
|
||||||
|
|
||||||
sx, sy := sx0/topLen, sy0/leftLen
|
|
||||||
sxStep := (sx1 - sx0) / float64(r-l) / topLen
|
|
||||||
syStep := (sy1 - sy0) / float64(r-l) / leftLen
|
|
||||||
|
|
||||||
fl, cr := int(math.Floor(l)), int(math.Ceil(r))
|
fl, cr := int(math.Floor(l)), int(math.Ceil(r))
|
||||||
for x := fl; x <= cr; x++ {
|
for x := fl; x <= cr; x++ {
|
||||||
fx := float64(x) + 0.5
|
fx := float64(x) + 0.5
|
||||||
if fx < l || fx >= r {
|
if fx < l || fx >= r {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fn(x, y, sx, sy)
|
sfx := fx - quad[0][0]
|
||||||
sx += sxStep
|
|
||||||
sy += syStep
|
var sx, sy float64
|
||||||
|
if math.Abs(leftv[0]) > math.Abs(leftv[1]) {
|
||||||
|
sx = (sfy - sfx*(leftv[1]/leftv[0])) / (topv[1] - topv[0]*(leftv[1]/leftv[0]))
|
||||||
|
sy = (sfx - topv[0]*sx) / leftv[0]
|
||||||
|
} else {
|
||||||
|
sx = (sfx - sfy*(leftv[0]/leftv[1])) / (topv[0] - topv[1]*(leftv[0]/leftv[1]))
|
||||||
|
sy = (sfy - topv[1]*sx) / leftv[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn(x, y, sx/topLen, sy/leftLen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue