internal/graphics/copy.go
func CopyImage(img image.Image) []byte {
	size := img.Bounds().Size()
	w, h := size.X, size.Y
	bs := make([]byte, 4*w*h)

	switch img := img.(type) {
	case *image.Paletted:
		b := img.Bounds()
		x0 := b.Min.X
		y0 := b.Min.Y
		x1 := b.Max.X
		y1 := b.Max.Y

		palette := make([]uint8, len(img.Palette)*4)
		for i, c := range img.Palette {
			rgba := color.RGBAModel.Convert(c).(color.RGBA)
			palette[4*i] = rgba.R
			palette[4*i+1] = rgba.G
			palette[4*i+2] = rgba.B
			palette[4*i+3] = rgba.A
		}
		// Even img is a subimage of another image, Pix starts with 0-th index.
		idx0 := 0
		idx1 := 0
		d := img.Stride - (x1 - x0)
		for j := 0; j < y1-y0; j++ {
			for i := 0; i < x1-x0; i++ {
				p := int(img.Pix[idx0])
				bs[idx1] = palette[4*p]
				bs[idx1+1] = palette[4*p+1]
				bs[idx1+2] = palette[4*p+2]
				bs[idx1+3] = palette[4*p+3]
				idx0++
				idx1 += 4
			}
			idx0 += d
		}
	default:
		dstImg := &image.RGBA{
			Pix:    bs,
			Stride: 4 * w,
			Rect:   image.Rect(0, 0, w, h),
		}
		draw.Draw(dstImg, image.Rect(0, 0, w, h), img, img.Bounds().Min, draw.Src)
	}
	return bs
}
func CopyImage(img image.Image) []byte {
	size := img.Bounds().Size()
	w, h := size.X, size.Y
	bs := make([]byte, 4*w*h)

	switch img := img.(type) {
	case *image.Paletted:
		b := img.Bounds()
		x0 := b.Min.X
		y0 := b.Min.Y
		x1 := b.Max.X
		y1 := b.Max.Y

		palette := make([]uint8, len(img.Palette)*4)
		for i, c := range img.Palette {
			rgba := color.RGBAModel.Convert(c).(color.RGBA)
			palette[4*i] = rgba.R
			palette[4*i+1] = rgba.G
			palette[4*i+2] = rgba.B
			palette[4*i+3] = rgba.A
		}
		// Even img is a subimage of another image, Pix starts with 0-th index.
		idx0 := 0
		idx1 := 0
		d := img.Stride - (x1 - x0)
		for j := 0; j < y1-y0; j++ {
			for i := 0; i < x1-x0; i++ {
				p := int(img.Pix[idx0])
				bs[idx1] = palette[4*p]
				bs[idx1+1] = palette[4*p+1]
				bs[idx1+2] = palette[4*p+2]
				bs[idx1+3] = palette[4*p+3]
				idx0++
				idx1 += 4
			}
			idx0 += d
		}
	default:
		dstImg := &image.RGBA{
			Pix:    bs,
			Stride: 4 * w,
			Rect:   image.Rect(0, 0, w, h),
		}
		draw.Draw(dstImg, image.Rect(0, 0, w, h), img, img.Bounds().Min, draw.Src)
	}
	return bs
}
func CopyImage ( img image . Image ) [ ] byte { size := img . Bounds ( ) . Size ( ) w , h := size . X , size . Y bs := make ( [ ] byte , 4 * w * h ) switch img := img . ( type ) { case * image . Paletted : b := img . Bounds ( ) x0 := b . Min . X y0 := b . Min . Y x1 := b . Max . X y1 := b . Max . Y palette := make ( [ ] uint8 , len ( img . Palette ) * 4 ) for i , c := range img . Palette { rgba := color . RGBAModel . Convert ( c ) . ( color . RGBA ) palette [ 4 * i ] = rgba . R palette [ 4 * i + 1 ] = rgba . G palette [ 4 * i + 2 ] = rgba . B palette [ 4 * i + 3 ] = rgba . A } // Even img is a subimage of another image, Pix starts with 0-th index. idx0 := 0 idx1 := 0 d := img . Stride - ( x1 - x0 ) for j := 0 ; j < y1 - y0 ; j ++ { for i := 0 ; i < x1 - x0 ; i ++ { p := int ( img . Pix [ idx0 ] ) bs [ idx1 ] = palette [ 4 * p ] bs [ idx1 + 1 ] = palette [ 4 * p + 1 ] bs [ idx1 + 2 ] = palette [ 4 * p + 2 ] bs [ idx1 + 3 ] = palette [ 4 * p + 3 ] idx0 ++ idx1 += 4 } idx0 += d } default : dstImg := & image . RGBA { Pix : bs , Stride : 4 * w , Rect : image . Rect ( 0 , 0 , w , h ) , } draw . Draw ( dstImg , image . Rect ( 0 , 0 , w , h ) , img , img . Bounds ( ) . Min , draw . Src ) } return bs }
// CopyImage copies img to a new RGBA image.
//
// Basically CopyImage just calls draw.Draw.
// If img is a paletted image, an optimized copying method is used.
//
// CopyImage is used only internally but it is exposed for testing.
CopyImage copies img to a new RGBA image . Basically CopyImage just calls draw . Draw . If img is a paletted image an optimized copying method is used . CopyImage is used only internally but it is exposed for testing .