这是来自 The Go Programming Language 的练习,作者是 Donovan & Kernighan:
Exercise 3.6: Supersampling is a technique to reduce the effect of pixelation by computing the color value at several points within each pixel and taking the average. The simplest method is to divide each pixel into four "subpixels". Implement it.
这是我的解决方案:
// Mandelbrot emits a PNG image of the Mandelbrot fractal.
package main
import (
//"fmt"
"image"
"image/color"
"image/png"
"math/cmplx"
"os"
)
func main() {
const (
xmin, ymin, xmax, ymax = -2, -2, +2, +2
width, height = 1024, 1024
swidth, sheight = width * 2, height * 2
)
var superColors [swidth][sheight]color.Color
for py := 0; py < sheight; py++ {
y := float64(py) / sheight * (ymax - ymin) + ymin
for px := 0; px < swidth; px++ {
x := float64(px) / swidth * (xmax - xmin) + xmin
z := complex(x, y)
superColors[px][py] = mandelbrot(z)
}
}
img := image.NewRGBA(image.Rect(0, 0, width, height))
for j := 0; j < height; j++ {
for i := 0; i < width; i++ {
si, sj := 2*i, 2*j
r1, g1, b1, a1 := superColors[si][sj].RGBA()
r2, g2, b2, a2 := superColors[si+1][sj].RGBA()
r3, g3, b3, a3 := superColors[si+1][sj+1].RGBA()
r4, g4, b4, a4 := superColors[si][sj+1].RGBA()
avgColor := color.RGBA{
uint8((r1 + r2 + r3 + r4) / 4),
uint8((g1 + g2 + g3 + g4) / 4),
uint8((b1 + b2 + b3 + b4) / 4),
uint8((a1 + a2 + a3 + a4) / 4)}
img.Set(i, j, avgColor)
}
}
png.Encode(os.Stdout, img)
}
func mandelbrot(z complex128) color.Color {
const iterations = 200
const contrast = 15
var v complex128
for n := uint8(0); n < iterations; n++ {
v = v*v + z
if cmplx.Abs(v) > 2 {
return color.Gray{255 - contrast*n}
}
}
return color.Black
}
然而,我的解决方案的结果似乎并没有降低像素化的影响:
我的解决方案错了吗?
最佳答案
在 go
中,当您通过 Color.RGBA()
获取 RGBA 值时,每个颜色分量(R
,G
,B
,A
)都用16位无符号表示,因此范围在 0-0xffff
(0-65535) 之间。但是,当您将图像保存为 PNG 时,每个分量都在 0-0xff
(0-255) 之间。您需要使用以下公式正确缩小每个颜色分量:
//e.g. red component
r := ((r1+r2+r3+r4)/4)*(255/65535) => (r1+r2+r3+r4)/1028
在您的情况下,正确的公式是:
avgColor := color.RGBA{
uint8((r1 + r2 + r3 + r4) / 1028),
uint8((g1 + g2 + g3 + g4) / 1028),
uint8((b1 + b2 + b3 + b4) / 1028),
uint8((a1 + a2 + a3 + a4) / 1028)}
关于go - 如何通过计算每个像素内几个点的颜色值并取平均值来减少像素化的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45094282/