英文:
Can I modify image's pixel value?
问题
我想在Go语言中做类似这样的事情:
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
// 类似于这样的操作:
src_img[x][y] = color.Black
}
}
是否可以只导入 "image"、"image/jpeg" 和 "image/color" 来实现这个功能?
英文:
I would like to do sth like this in Go:
for x := 0; x < width; x++ {
for y := 0; y < height; y++ {
// something similar to this:
src_img[x, y] = color.Black
}
}
is it possible to do this, importing only "image", "image/jpeg", "image/color"?
答案1
得分: 2
例如:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
const D = 12
img := image.NewGray(image.Rect(1, 1, D, D))
for x := 1; x <= D; x++ {
img.Set(x, x, color.Gray{byte(2 * x)})
}
for x := 1; x < D; x++ {
fmt.Printf("[%2d, %2d]: %5v\n", x, x, img.At(x, x))
}
}
输出:
[ 1, 1]: { 2}
[ 2, 2]: { 4}
[ 3, 3]: { 6}
[ 4, 4]: { 8}
[ 5, 5]: { 10}
[ 6, 6]: { 12}
[ 7, 7]: { 14}
[ 8, 8]: { 16}
[ 9, 9]: { 18}
[10, 10]: { 20}
[11, 11]: { 22}
英文:
For example:
package main
import (
"fmt"
"image"
"image/color"
)
func main() {
const D = 12
img := image.NewGray(image.Rect(1, 1, D, D))
for x := 1; x <= D; x++ {
img.Set(x, x, color.Gray{byte(2 * x)})
}
for x := 1; x < D; x++ {
fmt.Printf("[%2d, %2d]: %5v\n", x, x, img.At(x, x))
}
}
Output:
[ 1, 1]: { 2}
[ 2, 2]: { 4}
[ 3, 3]: { 6}
[ 4, 4]: { 8}
[ 5, 5]: { 10}
[ 6, 6]: { 12}
[ 7, 7]: { 14}
[ 8, 8]: { 16}
[ 9, 9]: { 18}
[10, 10]: { 20}
[11, 11]: { 22}
Recomended reading The Go image package article (additionally to the godocs).
答案2
得分: 1
image.RGBA 类型是在内存中存储图像并进行修改的首选方式。它实现了 draw.Image 接口,该接口具有方便的方法来设置像素:
Set(x, y int, c color.Color)
不幸的是,并非所有的解码器都以 RGBA 格式返回图像。其中一些解码器将图像保留在压缩格式中,其中并非每个像素都是可修改的。这对于许多只读用例来说速度更快,也是可以接受的。然而,如果你想编辑图像,可能需要复制它。例如:
src, _, err := image.Decode(file)
if err != nil {
log.Fatal(err)
}
rgba, ok := src.(*image.RGBA)
if !ok {
b := src.Bounds()
rgba = image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
draw.Draw(rgba, rgba.Bounds(), src, b.Min, draw.Src)
}
// rgba 现在是 *image.RGBA 类型,可以自由修改
rgba.Set(0, 0, color.RGBA{255, 0, 0, 255})
英文:
The image.RGBA type is the preferred way to store images in memory if you want to modify them. It implements the draw.Image interface that has a convenient method for setting pixels:
Set(x, y int, c color.Color)
Unfortunately not all decoders are returning the images in the RGBA format. Some of them are leaving the image in a compressed format where not every single pixel is modifiable. That's much faster and fine for a lot of read-only use-cases. If you want to edit the image however, you might need to copy it. For example:
src, _, err := image.Decode(file)
if err != nil {
log.Fatal(err)
}
rgba, ok := src.(*image.RGBA)
if !ok {
b := src.Bounds()
rgba = image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy()))
draw.Draw(rgba, rgba.Bounds(), src, b.Min, draw.Src)
}
// rgba is now a *image.RGBA and can be modified freely
rgba.Set(0, 0, color.RGBA{255, 0, 0, 255})
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论