2017-07-14 4 views
0

これは、移動プログラミング言語からの運動であるドノバン&カーニハンによって各ピクセル内のいくつかのポイントでカラー値を計算し、平均をとることによって、ピクセル化の効果を減らすにはどうすればよいですか?

演習3.6:スーパーサンプリングは、各画素内の複数の点における色値を計算することによってピクセル化の影響を低減する技術であります平均を取る。最も単純な方法は、各ピクセルを4つの「サブピクセル」に分割することです。それを実装する。ここで

私のソリューションです:

// 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 
} 

しかし、私の解決策の結果は、それがピクセレーションの影響を低減していないようです:

enter image description here

は、私の解決策を間違っています? go

答えて

1

もしColor.RGBA()介してRGBA値を取得した場合に、各色成分(RGBA)はこのように範囲(0〜65535)0-0xffffとの間にある、16ビットの符号なしで表されます。ただし、イメージを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)} 

UPDATE:
出力画像は
Supersampled Madlebrot imageのように見えます

+0

魔法 '1028'値とは何ですか? – zerkms

+1

@zerkmsこれは1/1028に等しい255 /(4 * 65535)の簡略化された形式です。 – putu

+0

ああ、それに気付かなかった。 – zerkms

0

この場合、右シフト演算を実行すると、uint32からuint8に値を変換できますn:

r := r >> 8 

これにより、計算時間が短縮されます。

も参照してください: Why does golang RGBA.RGBA() method use | and <<?

関連する問題