使用Image.Image或* image.RGBA的Set()方法
今年夏天我正在做一些Go图像包和我的空闲时间练习。使用Image.Image或* image.RGBA的Set()方法
package main import (
"os"
"image"
"image/png"
"image/color"
"log"
"fmt"
"reflect"
)
func main(){
file , err := os.OpenFile("C:/Sources/go3x3.png", os.O_RDWR, os.FileMode(0777))
if err != nil {
log.Fatal(err)
}
img , err := png.Decode(file)
if err != nil {
log.Fatal(err)
}
img.At(0,0).RGBA()
fmt.Println("type:", reflect.TypeOf(img))
m := image.NewRGBA(image.Rect(0, 0, 640, 480))
fmt.Println("type:", reflect.TypeOf(m))
m.Set(5, 5, color.RGBA{255, 0, 0, 255})
img.Set(0, 0, color.RGBA{136, 0, 21, 255})
}
这里的问题是,当我注释掉img.Set
运行它,我得到这样的结果
type: *image.RGBA type: *image.RGBA
,但是当它注释掉我得到一个错误说
img.Set undefined (type image.Image has no field or method Set)
我假设我使用反射错误,我仍然完全掌握Go中的整个界面和类型定义。
回答:
reflect.TypeOf(img)
为您提供接口img
中的值的反射类型,如果它是一个接口。在这种情况下,img
是的接口,image.Image
其中包含*image.RGBA
。
可以通过转换img
到*image.RGBA
解决您的代码,或更有力,定义与右Set
方法的接口类型,并转换img
到(该draw.Image
接口"image/draw"
完全适用于这一点,因为通过@注意DaveC)。如果您不确定png.Decode
将始终为您提供.png文件的*image.RGBA
,则该接口类型更可取。
img.(*image.RGBA).Set(0, 0, color.RGBA{136, 0, 21, 255})
或
type Setter interface { Set(x, y int, c color.Color)
}
img.(Setter).Set(0, 0, color.RGBA{136, 0, 21, 255})
或(可能是最好的):
import "image/draw" ...
img.(draw.Image).Set(0, 0, color.RGBA{136, 0, 21, 255})
回答:
的编译器是正确的,则image.Image类型是一个接口,不包括set()函数。
我不是图像库的专家,但粗略地看看这些类型似乎建议您可以采用图像类型并使用Bounds()
方法来获得image.Rectangle以创建一个新的RGBA类型,如以前在您的示例中所做的那样码。
// Your current image manipulation m := image.NewRGBA(image.Rect(0, 0, 640, 480))
fmt.Println("type:", reflect.TypeOf(m))
m.Set(5, 5, color.RGBA{255, 0, 0, 255})
// You can create a image.RGBA type by passing the image.Rectangle
// returned from image.Image.Bounds()
m = image.NewRGBA(img.Bounds())
m.Set(0, 0, color.RGBA{136, 0, 21, 255})
这是对您的类型问题的严格回答,但我没有任何保证它会实现您的最终目标。
回答:
为了扩展 Anonymous' answer:
png.Decode
可以创建几个不同的基础的图像类型(*image.Gray
,*image.RGBA
,*image.Paletted
,*image.NRGBA
等)中的一个。 它返回它创建的任何图像作为image.Image
接口,其中提供对数据的只读访问。
但是,它返回的所有(最?)实际图像类型都实现了用于简单写入访问的Set
方法。 您可以安全地测试和使用此方法的方式是通过image/draw
包中的现有draw.Image
接口。这只是这样的:
// From image/draw: // Image is an image.Image with a Set method to change a single pixel.
type Image interface {
image.Image
Set(x, y int, c color.Color)
}
所以,你可以这样做:
3210Playground(显示了一个例子呼吁所有image.Image
方法以及Set
)。
以上是 使用Image.Image或* image.RGBA的Set()方法 的全部内容, 来源链接: utcz.com/qa/261316.html