ebiten: allow passing ebiten.Image to NewImageFromImage

Closes #1917
This commit is contained in:
Hajime Hoshi 2022-04-02 06:10:20 +09:00
parent 3fafc05411
commit 9ddcf58728
2 changed files with 54 additions and 0 deletions

View File

@ -808,11 +808,22 @@ func NewImage(width, height int) *Image {
// Reusing the same image by Clear is much more efficient than creating a new image.
//
// NewImageFromImage panics if RunGame already finishes.
//
// The returned image's origin is always (0, 0). The source's bounds are not respected.
func NewImageFromImage(source image.Image) *Image {
if isRunGameEnded() {
panic(fmt.Sprintf("ebiten: NewImage cannot be called after RunGame finishes"))
}
// If the given image is an Ebiten image, use DrawImage instead of reading pixels from the source.
// This works even before the game loop runs.
if source, ok := source.(*Image); ok {
size := source.Bounds().Size()
i := NewImage(size.X, size.Y)
i.DrawImage(source, nil)
return i
}
size := source.Bounds().Size()
width, height := size.X, size.Y
if width <= 0 {

View File

@ -2846,3 +2846,46 @@ func TestTooManyVertices(t *testing.T) {
// Confirm this doesn't freeze.
dst.At(0, 0)
}
func TestImageNewImageFromEbitenImage(t *testing.T) {
const (
w = 16
h = 16
)
pix := make([]byte, 4*w*h)
for j := 0; j < h; j++ {
for i := 0; i < w; i++ {
idx := 4 * (i + j*w)
pix[idx] = byte(i)
pix[idx+1] = byte(j)
pix[idx+2] = 0
pix[idx+3] = 0xff
}
}
img0 := ebiten.NewImage(w, h)
img0.ReplacePixels(pix)
img1 := ebiten.NewImageFromImage(img0)
for j := 0; j < h; j++ {
for i := 0; i < w; i++ {
got := img1.At(i, j)
want := color.RGBA{byte(i), byte(j), 0, 0xff}
if got != want {
t.Errorf("img1.At(%d, %d): got: %v, want: %v", i, j, got, want)
}
}
}
img2 := ebiten.NewImageFromImage(img0.SubImage(image.Rect(4, 4, 12, 12)))
for j := 0; j < h/2; j++ {
for i := 0; i < w/2; i++ {
got := img2.At(i, j)
want := color.RGBA{byte(i + 4), byte(j + 4), 0, 0xff}
if got != want {
t.Errorf("img1.At(%d, %d): got: %v, want: %v", i, j, got, want)
}
}
}
}