// surfaceManipulate is an internal function that creates a new surface, gets // metadata, and then calls a passed-in function to actually do something to it, // e.g. horizontally flip all the pixels. // // Note: this only supports manipulations that leave the Surface the same // dimensions. It could potentially be generalized to handle manipulations that // leave the Surface with the same number of pixels. func surfaceManipulate(src *sdl.Surface, f func(src *sdl.Surface, srcWBytes, bytesPerPixel int32, srcPx, destPx []byte)) (*sdl.Surface, error) { pf := src.Format pixels := src.Pixels() bytesPP := int32(pf.BytesPerPixel) bitsPP := int32(pf.BitsPerPixel) newSurface, err := sdl.CreateRGBSurface(0, src.W, src.H, bitsPP, pf.Rmask, pf.Gmask, pf.Bmask, pf.Amask) if err != nil { return nil, err } pixelsDest := newSurface.Pixels() srcWBytes := int32(src.W * bytesPP) // Perform the manipulation f(src, srcWBytes, bytesPP, pixels, pixelsDest) return newSurface, nil }
func SurfaceConvertToImage(s *sdl.Surface) (img image.Image, err error) { switch s.Format.Format { case sdl.PIXELFORMAT_RGBA8888, sdl.PIXELFORMAT_RGBX8888: i := &image.RGBA{Rect: image.Rect(0, 0, int(s.W), int(s.H))} i.Pix = s.Pixels() img = i case sdl.PIXELFORMAT_INDEX8: i := image.NewRGBA(image.Rect(0, 0, int(s.W), int(s.H))) key, err := s.GetColorKey() if err != nil { return nil, err } // fmt.Println(s.PixelNum(), len(s.Pixels()), len(i.Pix), s.W, s.H, s.Pitch, s.Format.BitsPerPixel, s.Format.BytesPerPixel, key) l := len(s.Pixels()) var r, g, b, a uint8 for n := 0; n < l; n += 1 { pixel := s.Pixels()[n] if pixel == uint8(key) { r, g, b, a = 0, 0, 0, 0 } else { r, g, b, a = sdl.GetRGBA(uint32(pixel), s.Format) } p := i.PixOffset(n%int(s.Pitch), n/int(s.Pitch)) i.Pix[p], i.Pix[p+1], i.Pix[p+2], i.Pix[p+3] = r, g, b, a } img = i default: sx, err := s.ConvertFormat(sdl.PIXELFORMAT_RGBX8888, 0) if err != nil { return nil, err } i := &image.RGBA{Rect: image.Rect(0, 0, int(s.W), int(s.H))} i.Pix = sx.Pixels() img = i } return }