酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows Mobileで減色処理をおこなう

ちょっとした画像検索ツールを作りたいと思い、はてなフォトライフみたいな色タグを実装してみようと始めました。

まずは色タグの基準となるカラーテーブルを作成します。ここでは簡単にRGB2階調の計8色分にしてみたいと思います。後々RGB成分を使いたいので簡単に扱えるようColor型のListにします。

    Private Function CreateColorTable() As List(Of Color)
        Dim list As New List(Of Color)

        For r = 0 To 1
            For g = 0 To 1
                For b = 0 To 1

                    list.Add(Color.FromArgb(r * 255, g * 255, b * 255))

                Next b
            Next g
        Next r

        Return list
    End Function

念の為、実際にどのようなカラーテーブルになっているのか確認してみます。ほい。ユニクロでありそうな原色原色したカラーテーブルが出来ました。

        Using g = Graphics.FromImage(PictureBox1.Image)

            Dim w = Math.Floor(bmp.Width / 3)
            Dim h = Math.Floor(bmp.Height / 3)
            Dim max = 2
            Dim index = 0

            For i = 0 To max
                For j = 0 To max
                    g.FillRectangle(New SolidBrush(table(index)), _
                                    New Rectangle(w * i, h * j, w, h))
                    index += 1
                Next j
            Next i
        End Using


        Dim ht As New Hashtable()
        For i = 0 To table.Count - 1
            ht.Add(table(i), 0)
        Next i

        For i = 0 To bmp.Width - 1
            For j = 0 To bmp.Height - 1

                Dim pixel = bmp.GetPixel(i, j)
                Dim r As Double = pixel.R
                Dim g As Double = pixel.G
                Dim b As Double = pixel.B

                Dim index = 0
                Dim min As Double = Double.MaxValue
                For Each tableColor In table

                    ' 画像のピクセルの色とカラーテーブルの色の「距離」を求める
                    Dim tr As Double = r - tableColor.R
                    Dim tg As Double = g - tableColor.G
                    Dim tb As Double = b - tableColor.B
                    Dim dist As Double = Math.Sqrt(tr ^ 2 + tg ^ 2 + tb ^ 2)

                    ' 色間の最小距離値の更新
                    If (dist < min) Then
                        min = dist
                        index = table.IndexOf(tableColor)
                    End If
                Next tableColor

                ht(table(index)) += 1
                'bmp.SetPixel(i, j, table(index))
            Next j
        Next i

        Dim sorted = From item As DictionaryEntry In ht _
                     Order By item.Value Descending _
                     Select item

        For Each s As DictionaryEntry In sorted
            Console.WriteLine(DirectCast(s.Key, Color).Name & ":" & s.Value)
        Next