here u go

This commit is contained in:
elee 2022-03-25 05:23:31 -05:00
parent 4057b3c3c6
commit 0f5e1f4c0a
8 changed files with 105 additions and 54 deletions

View File

@ -6,6 +6,7 @@ import (
"image/draw" "image/draw"
"git.tuxpa.in/a/zlog/log" "git.tuxpa.in/a/zlog/log"
"github.com/phrozen/blend"
"gitlab.com/gfxlabs/gfximg/apng" "gitlab.com/gfxlabs/gfximg/apng"
) )
@ -30,54 +31,89 @@ func (n *Nori) ExportAnimation() (*apng.APNG, error) {
a := &apng.APNG{ a := &apng.APNG{
Frames: make([]apng.Frame, 0, len(g.Images)), Frames: make([]apng.Frame, 0, len(g.Images)),
} }
images := make([]*image.NRGBA64, 0, len(n.Animations))
for i := 0; i < len(n.Animations); i++ { for i := 0; i < len(n.Animations); i++ {
for _, v := range n.Animations[i].Frames { if len(n.Animations[i].Frames) < 1 {
canvasRect := image.Rect(0, 0, 0, 0) continue
for _, plane := range v.Planes {
if int(plane.BitmapId) >= len(n.Gawi.Images) {
log.Printf("could not find bitmap %d, only have %d", plane.BitmapId, len(n.Gawi.Images))
}
bitmap := n.Gawi.Images[plane.BitmapId]
canvasRect = canvasRect.Union(bitmap.Img.Bounds())
}
img := image.NewRGBA64(canvasRect)
for _, plane := range v.Planes {
bitmap := n.Gawi.Images[plane.BitmapId]
transparent := false
//flipx
if plane.RenderFlag&1 != 0 {
}
//flipy
if plane.RenderFlag&2 != 0 {
}
// is transparent
if plane.RenderFlag&0x20 != 0 {
transparent = true
}
_ = transparent
switch plane.Blend {
case BlendMode_Alpha:
case BlendMode_Mul, BlendMode_Mul7:
case BlendMode_Add, BlendMode_Add8:
case BlendMode_InvertMul, BlendMode_InvertMul5:
case BlendMode_None:
break
default:
return nil, fmt.Errorf("unknown blend mode: %d", plane.Blend)
}
draw.Draw(img,
img.Rect,
bitmap.Img,
image.Point{X: int(plane.PlaneX),
Y: int(plane.PlaneY)}, draw.Over)
}
fr := apng.Frame{
Image: g.Images[i].Img,
DelayNumerator: uint16(g.Images[i].Delay),
DelayDenominator: 1000,
}
a.Frames = append(a.Frames, fr)
} }
planes := n.Animations[i].Frames[0].Planes
var canvasRect image.Rectangle
for _, plane := range planes {
if int(plane.BitmapId) >= len(n.Gawi.Images) {
log.Printf("could not find bitmap %d, only have %d", plane.BitmapId, len(n.Gawi.Images))
}
bitmap := n.Gawi.Images[plane.BitmapId]
pt := image.Pt(int(plane.PlaneX), int(plane.PlaneY)) // where to put the point
rc := bitmap.Img.Bounds()
canvasRect = canvasRect.Union(rc.Add(pt))
}
img := image.NewNRGBA64(canvasRect)
for _, plane := range planes {
bitmap := n.Gawi.Images[plane.BitmapId]
transparent := false
//flipx
if plane.RenderFlag&1 != 0 {
}
//flipy
if plane.RenderFlag&2 != 0 {
}
// is transparent
if plane.RenderFlag&0x20 != 0 {
transparent = true
}
_ = transparent
pt := image.Pt(int(plane.PlaneX), int(plane.PlaneY)) // where to put the point
src := bitmap.Img
sr := src.Bounds()
r := image.Rectangle{pt, pt.Add(sr.Size())}
switch plane.Blend {
case BlendMode_Alpha:
case BlendMode_Mul, BlendMode_Mul7:
blend.BlendImage(img, bitmap.Img, blend.Multiply)
case BlendMode_Add, BlendMode_Add8:
blend.BlendImage(img, bitmap.Img, blend.Add)
case BlendMode_InvertMul, BlendMode_InvertMul5:
blend.BlendImage(img, bitmap.Img, blend.Multiply)
case BlendMode_None:
default:
return nil, fmt.Errorf("unknown blend mode: %d", plane.Blend)
}
draw.Draw(img,
r,
src,
sr.Min,
draw.Over,
)
}
if len(planes) > 0 {
images = append(images, img)
}
}
or := images[0].Bounds()
for _, realFrame := range images {
or = realFrame.Bounds().Union(or)
}
// TODO: this is bugged
for i, realFrame := range images {
big := image.NewNRGBA64(or)
draw.Draw(
big,
big.Rect,
realFrame,
realFrame.Bounds().Min,
draw.Src,
)
fr := apng.Frame{
Image: big,
DisposeOp: apng.DISPOSE_OP_PREVIOUS,
BlendOp: apng.BLEND_OP_OVER,
DelayDenominator: 1000,
}
if g.Images[i].Delay != 0 {
fr.DelayNumerator = uint16(g.Images[i].Delay)
}
a.Frames = append(a.Frames, fr)
} }
return a, nil return a, nil
} }

View File

@ -51,11 +51,13 @@ func (i *Image) Decode(rd *bufio.Reader, palette *PaletteSection) error {
red := uint8(((0x7c00 & bgr) >> 10) * 255 / 31) red := uint8(((0x7c00 & bgr) >> 10) * 255 / 31)
green := uint8(((0x3e0 & bgr) >> 5) * 255 / 31) green := uint8(((0x3e0 & bgr) >> 5) * 255 / 31)
blue := uint8((0x1f & bgr) * 255 / 31) blue := uint8((0x1f & bgr) * 255 / 31)
if red != 0 && blue != 0 && green != 0 { alpha := uint8(0xff)
if red == 0xff && blue == 0xff {
alpha = 0x00
} }
col := &color.RGBA{ col := &color.RGBA{
red, green, blue, red, green, blue,
0xff, alpha,
} }
cf.Set(idx%int(i.Width), idx/int(i.Width), col) cf.Set(idx%int(i.Width), idx/int(i.Width), col)
} }
@ -68,9 +70,13 @@ func (i *Image) Decode(rd *bufio.Reader, palette *PaletteSection) error {
if err != nil { if err != nil {
return err return err
} }
alpha := uint8(0xff)
col := &color.RGBA{ col := &color.RGBA{
rgb[0], rgb[1], rgb[2], rgb[0], rgb[1], rgb[2],
0xff, alpha,
}
if rgb[0] == 0xff && rgb[2] == 0xff {
alpha = 0x00
} }
cf.Set(idx%int(i.Width), idx/int(i.Width), col) cf.Set(idx%int(i.Width), idx/int(i.Width), col)
} }

View File

@ -5,7 +5,6 @@ import (
"os" "os"
"testing" "testing"
"git.tuxpa.in/a/zlog/log"
"gitlab.com/gfxlabs/gfximg/apng" "gitlab.com/gfxlabs/gfximg/apng"
) )
@ -59,14 +58,21 @@ func TestParsePalette(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("export: %s", err) t.Errorf("export: %s", err)
} }
writeApng(a, "./nori_test/palette.apng") err = writeApng(a, "./nori_test/palette.apng")
if err != nil {
t.Errorf("export: %s", err)
}
} }
func writeApng(a *apng.APNG, fp string) { func writeApng(a *apng.APNG, fp string) error {
out := new(bytes.Buffer) out := new(bytes.Buffer)
err := apng.Encode(out, *a) err := apng.Encode(out, *a)
if err != nil { if err != nil {
log.Errorf("fail to encode apng %s", err) return err
} }
os.WriteFile(fp, out.Bytes(), 0740) err = os.WriteFile(fp, out.Bytes(), 0740)
if err != nil {
return err
}
return nil
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 577 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 60 KiB

1
go.mod
View File

@ -10,5 +10,6 @@ require (
require ( require (
github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-isatty v0.0.14 // indirect
github.com/phrozen/blend v0.0.0-20210220204729-f26b6cf7a28e // indirect
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
) )

2
go.sum
View File

@ -6,6 +6,8 @@ github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZb
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/phrozen/blend v0.0.0-20210220204729-f26b6cf7a28e h1:r8tWFp1HMiodzOwFtEVZ41Q0PuX/G5PWHZS14kAQMoI=
github.com/phrozen/blend v0.0.0-20210220204729-f26b6cf7a28e/go.mod h1:8LjAsvtcQgvNmMQZ/iSuduOKYgRA37KcsgPg8ZC6Krc=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
gitlab.com/gfxlabs/gfximg v0.0.5 h1:jtHE6In6axz0zGPy7YnLIZV9RFdcFEZzpdqoXb52K9s= gitlab.com/gfxlabs/gfximg v0.0.5 h1:jtHE6In6axz0zGPy7YnLIZV9RFdcFEZzpdqoXb52K9s=