とりあえずレポジトリの作成をすることにした。
ここ
最終的には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
}
出力結果
※元画像は前回のと同様
本当にあってるかは謎だけど、それっぽい。
階調数変換
下のような式になるそうです。謎すぎるので、サンプルコードを見て考えましょう
$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」で元に戻すと、名前のまんまなんですな。
出力結果
それっぽい、ボチボチテスト方法を考えないとしょうもない
と思ったから関数切り出し始めたんですけどね。
その他の課題
- 関数ポインタ見たいの渡せばfor分は省略できると思う。
- テストプログラムどうやって書くの?
とりあえず、やるかどうかは根性が発生しだい。
修正しても記事のアップデート面倒だな、と思いました。