From 26a58d20b3595d992e901bd6a9e6ab9455c24498 Mon Sep 17 00:00:00 2001 From: Terra Brown Date: Tue, 30 Aug 2022 14:10:10 -0400 Subject: [PATCH] internal/graphicscommand: enable `EBITENGINE_INTERNAL_IMAGES_KEY` on browsers (#2283) Closes #2270 Co-authored-by: Hajime Hoshi --- doc.go | 2 +- imagedumper_notmobile.go | 4 -- internal/graphicscommand/image.go | 6 +++ internal/graphicscommand/image_js.go | 60 +++++++++++++++++-------- internal/graphicscommand/image_notjs.go | 21 +++++++-- internal/restorable/images.go | 10 ++--- 6 files changed, 71 insertions(+), 32 deletions(-) diff --git a/doc.go b/doc.go index 646745c80..5ac46efa3 100644 --- a/doc.go +++ b/doc.go @@ -63,7 +63,7 @@ // // `EBITENGINE_INTERNAL_IMAGES_KEY` environment variable specifies the key // to dump all the internal images. This is valid only when the build tag -// 'ebitenginedebug' is specified. This works only on desktops. +// 'ebitenginedebug' is specified. This works only on desktops and browsers. // // `EBITENGINE_GRAPHICS_LIBRARY` environment variable specifies the graphics library. // If the specified graphics library is not available, RunGame returns an error. diff --git a/imagedumper_notmobile.go b/imagedumper_notmobile.go index 45271d5fe..25d57b5ec 100644 --- a/imagedumper_notmobile.go +++ b/imagedumper_notmobile.go @@ -71,10 +71,6 @@ func dumpInternalImages() error { return err } - if err := os.Mkdir(dir, 0755); err != nil { - return err - } - if err := ui.DumpImages(dir); err != nil { return err } diff --git a/internal/graphicscommand/image.go b/internal/graphicscommand/image.go index a9758a223..cc969c7a9 100644 --- a/internal/graphicscommand/image.go +++ b/internal/graphicscommand/image.go @@ -18,6 +18,8 @@ import ( "image" "io" "sort" + "strconv" + "strings" "github.com/hajimehoshi/ebiten/v2/internal/affine" "github.com/hajimehoshi/ebiten/v2/internal/debug" @@ -192,6 +194,10 @@ func (i *Image) IsInvalidated() bool { return i.image.IsInvalidated() } +func (i *Image) dumpName(path string) string { + return strings.ReplaceAll(path, "*", strconv.Itoa(i.id)) +} + // dumpTo dumps the image to the specified writer. // // If blackbg is true, any alpha values in the dumped image will be 255. diff --git a/internal/graphicscommand/image_js.go b/internal/graphicscommand/image_js.go index 6da986a2a..15d8a74b5 100644 --- a/internal/graphicscommand/image_js.go +++ b/internal/graphicscommand/image_js.go @@ -15,43 +15,67 @@ package graphicscommand import ( + "archive/zip" "bytes" "image" - "path/filepath" - "strconv" - "strings" "syscall/js" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" ) -func (i *Image) Dump(graphicsDriver graphicsdriver.Graphics, path string, blackbg bool, rect image.Rectangle) error { - // Screen image cannot be dumped. - if i.screen { - return nil - } - - path = strings.ReplaceAll(path, "*", strconv.Itoa(i.id)) - path = filepath.Base(path) - +func download(buf *bytes.Buffer, mime string, path string) { global := js.Global() - buf := &bytes.Buffer{} - if err := i.dumpTo(buf, graphicsDriver, blackbg, rect); err != nil { - return err - } - jsData := global.Get("Uint8Array").New(buf.Len()) js.CopyBytesToJS(jsData, buf.Bytes()) a := global.Get("document").Call("createElement", "a") blob := global.Get("Blob").New( []interface{}{jsData}, - map[string]interface{}{"type": "image/png"}, + map[string]interface{}{"type": mime}, ) a.Set("href", global.Get("URL").Call("createObjectURL", blob)) a.Set("download", path) a.Call("click") +} + +func (i *Image) Dump(graphicsDriver graphicsdriver.Graphics, path string, blackbg bool, rect image.Rectangle) error { + // Screen image cannot be dumped. + if i.screen { + return nil + } + + buf := &bytes.Buffer{} + if err := i.dumpTo(buf, graphicsDriver, blackbg, rect); err != nil { + return err + } + + download(buf, "image/png", i.dumpName(path)) + + return nil +} + +// DumpImages dumps all the specified images to the specified directory. +// +// This is for testing usage. +func DumpImages(images []*Image, graphicsDriver graphicsdriver.Graphics, dir string) error { + buf := &bytes.Buffer{} + zw := zip.NewWriter(buf) + + for _, img := range images { + f, err := zw.Create(img.dumpName("*.png")) + if err != nil { + return err + } + + if err := img.dumpTo(f, graphicsDriver, false, image.Rect(0, 0, img.width, img.height)); err != nil { + return err + } + } + + zw.Close() + + download(buf, "archive/zip", dir+".zip") return nil } diff --git a/internal/graphicscommand/image_notjs.go b/internal/graphicscommand/image_notjs.go index 10ba4afc1..d805f418e 100644 --- a/internal/graphicscommand/image_notjs.go +++ b/internal/graphicscommand/image_notjs.go @@ -20,8 +20,7 @@ package graphicscommand import ( "image" "os" - "strconv" - "strings" + "path/filepath" "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver" ) @@ -32,7 +31,7 @@ func (i *Image) Dump(graphicsDriver graphicsdriver.Graphics, path string, blackb return nil } - path = strings.ReplaceAll(path, "*", strconv.Itoa(i.id)) + path = i.dumpName(path) f, err := os.Create(path) if err != nil { return err @@ -45,3 +44,19 @@ func (i *Image) Dump(graphicsDriver graphicsdriver.Graphics, path string, blackb return nil } + +// DumpImages dumps all the current images to the specified directory. +// +// This is for testing usage. +func DumpImages(images []*Image, graphicsDriver graphicsdriver.Graphics, dir string) error { + if err := os.Mkdir(dir, 0755); err != nil { + return err + } + + for _, img := range images { + if err := img.Dump(graphicsDriver, filepath.Join(dir, "*.png"), false, image.Rect(0, 0, img.width, img.height)); err != nil { + return err + } + } + return nil +} diff --git a/internal/restorable/images.go b/internal/restorable/images.go index 5fa9b6a86..d9f424903 100644 --- a/internal/restorable/images.go +++ b/internal/restorable/images.go @@ -15,8 +15,6 @@ package restorable import ( - "image" - "path/filepath" "runtime" "github.com/hajimehoshi/ebiten/v2/internal/debug" @@ -125,12 +123,12 @@ func RestoreIfNeeded(graphicsDriver graphicsdriver.Graphics) error { // // This is for testing usage. func DumpImages(graphicsDriver graphicsdriver.Graphics, dir string) error { + images := make([]*graphicscommand.Image, 0, len(theImages.images)) for img := range theImages.images { - if err := img.Dump(graphicsDriver, filepath.Join(dir, "*.png"), false, image.Rect(0, 0, img.width, img.height)); err != nil { - return err - } + images = append(images, img.image) } - return nil + + return graphicscommand.DumpImages(images, graphicsDriver, dir) } // add adds img to the images.