LoginSignup
0
0

More than 5 years have passed since last update.

goで読み込んで濃淡を変更する。

Last updated at Posted at 2016-12-24

とりあえずレポジトリの作成をすることにした。

ここ
最終的にはWEBのツールみたいにしようと思ったけど、なんか趣旨ずれそうですね。

本日の課題

以下を実施いていく
主に
1. 濃度反転を使用して画像を加工する。
2. 階調数変換を使用して画像を加工する

裏で
3. ソースコードの分割
4. 今回の作成分はinterfaceにしとく(結果ソースの分割)

濃度反転

$Z' = Z_{max} - Z $
で出るそうです。
要するに最大から引けって話ですな。

ソースコード

「// 反転する」以降のところくらいしか見所はないですね。
あと、勝手にmath.MaxInt16を最大にしてるのどうかと思う。
けど、どうなんだろ?詳しくはjpegについての話になったりして後で詰まるからそのうちでいいや

func (ef *effect) ReverseConcentration() image.Image {
    rect := ef.inputImage.Bounds()
    width := rect.Size().X
    height := rect.Size().Y
    rgba := image.NewRGBA(rect)
    for x := 0; x < width; x++ {
        for y := 0; y < height; y++ {
            var col color.RGBA64
            // 座標(x,y)のR, G, B, α の値を取得
            r, g, b, a := ef.inputImage.At(x, y).RGBA()
            //反転する
            col.R = math.MaxInt16 - uint16(r)
            col.G = math.MaxInt16 - uint16(g)
            col.B = math.MaxInt16 - uint16(b)
            col.A = uint16(a)
            rgba.Set(x, y, col)
        }
    }
    return rgba
}

出力結果

※元画像は前回のと同様
plant4_revcon.jpg

本当にあってるかは謎だけど、それっぽい。

階調数変換

下のような式になるそうです。謎すぎるので、サンプルコードを見て考えましょう
$Z_1 = \frac{Z_{max}}{n}$

$Z_2 = \frac{Z_{max}}{n-1}$

n がその階調になる。から今回は4

ソースコード

まず大元の関数、ボチボチ共通化を考えましょうね、という話。

// 4階調にする
func (ef *effect) FourTone() image.Image {
    rect := ef.inputImage.Bounds()
    width := rect.Size().X
    height := rect.Size().Y
    rgba := image.NewRGBA(rect)

    // この処理での特殊な値
    //  4階調とする
    tone := 4
    for x := 0; x < width; x++ {
        for y := 0; y < height; y++ {
            // 座標(x,y)のR, G, B, α の値を取得
            r, g, b, a := ef.inputImage.At(x, y).RGBA()
            effectFunction := fourToneColor
            rgba.Set(x, y, effectFunction(r, g, b, a, tone))
        }
    }
    return rgba
    }

変換の中身です。

func fourToneColor(r, g, b, a uint32, tone int) color.RGBA64 {
    var col color.RGBA64
    z1 := uint16(math.MaxUint16 / (tone))
    z2 := uint16(math.MaxUint16 / (tone - 1))
    vals := []uint32{r, g, b}
    ptr := []*uint16{&col.R, &col.G, &col.B}
    //  計算する
    for i, v := range vals {
        *ptr[i] = (uint16(v) / z1) * z2
    }
    col.A = uint16(a)
    return col
}

書くとわかりますが「uint16(v) / z1」で情報の密度を1/4(4階調)にして、「* z2」で元に戻すと、名前のまんまなんですな。

出力結果

plant4_fourtone.jpg
それっぽい、ボチボチテスト方法を考えないとしょうもない
と思ったから関数切り出し始めたんですけどね。

その他の課題

  1. 関数ポインタ見たいの渡せばfor分は省略できると思う。
  2. テストプログラムどうやって書くの?

とりあえず、やるかどうかは根性が発生しだい。
修正しても記事のアップデート面倒だな、と思いました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0