ちょっとした画像検索ツールを作りたいと思い、はてなフォトライフみたいな色タグを実装してみようと始めました。
まずは色タグの基準となるカラーテーブルを作成します。ここでは簡単に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