Как отобрать картинки с определенным цветом? - C#
Формулировка задачи:
Есть папка с картинками (около 1к).
Как отобрать картинки, где есть красный цвет?
В какую сторону смотреть и реально ли это вообще?
Решение задачи: «Как отобрать картинки с определенным цветом?»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
namespace WindowsFormsApplication360
{
public partial class Form1 : Form
{
private List<ImageInfo> images = new List<ImageInfo>();
private List<ImageInfo> filtered = new List<ImageInfo>();
public Form1()
{
InitializeComponent();
tbFolder.Text = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
}
private void lbColor_Click(object sender, EventArgs e)
{
var dlg = new ColorDialog() {Color = lbColor.BackColor};
if(dlg.ShowDialog() == DialogResult.OK)
{
lbColor.BackColor = dlg.Color;
filtered = Filter(lbColor.BackColor);
lbIndexed.Text = "Indexed: " + images.Count;
lbFiltered.Text = "Filtered: " + filtered.Count;
flMain.Build(filtered);
}
}
private void btFolder_Click(object sender, EventArgs e)
{
var dlg = new FolderBrowserDialog();
if(dlg.ShowDialog() == DialogResult.OK)
tbFolder.Text = dlg.SelectedPath;
}
private List<ImageInfo> Index(string path)
{
var res = new List<ImageInfo>();
foreach(var file in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
switch(Path.GetExtension(file).ToLower())
{
case ".png":
case ".jpg":
case ".bmp":
case ".gif":
try
{
res.Add(new ImageInfo(file));
}
catch {/*skip*/ }
break;
}
return res;
}
private List<ImageInfo> Filter(Color c)
{
var filtered = new List<ImageInfo>();
const float minRate = 0.01f;
foreach(var im in images)
{
if (im.Hist.GetFrequency(c) >= minRate)
filtered.Add(im);
}
return filtered;
}
private void btIndex_Click(object sender, EventArgs e)
{
Cursor = Cursors.WaitCursor;
images = Index(tbFolder.Text);
filtered = Filter(lbColor.BackColor);
flMain.Build(filtered);
lbIndexed.Text = "Indexed: " + images.Count;
lbFiltered.Text = "Filtered: " + filtered.Count;
Cursor = Cursors.Default;
}
private void flMain_PaintItem(object sender, FastTreeNS.PaintItemContentEventArgs e)
{
var item = filtered[e.Info.ItemIndex];
using (var bmp = new Bitmap(item.FilePath))
e.Graphics.DrawImage(bmp, e.Info.FullRect);
}
private void flMain_ItemSelectedStateChanged(object sender, FastTreeNS.ItemSelectedStateChangedEventArgs e)
{
if(e.Selected)
{
pbMain.ImageLocation = filtered[e.ItemIndex].FilePath;
}
}
}
/// <summary>
/// Информация о картинке (путь, гистограммы)
/// </summary>
class ImageInfo
{
public Hist Hist = new Hist();
public string FilePath { get; private set; }
public ImageInfo(string imagePath)
{
this.FilePath = imagePath;
using (var bmp = new Bitmap(imagePath))
using (var thumb = (Bitmap)bmp.GetThumbnailImage(100, 100, null, IntPtr.Zero))
using (var wr = new ImageWrapper(thumb))
foreach(var p in wr)
Hist.Add(wr[p]);
}
}
/// <summary>
/// Гистограмма цветов
/// </summary>
class Hist
{
private int[,,] sum = new int[32, 32, 32];
private int count;
public void Add(Color c)
{
sum[c.R/8, c.G/8, c.B/8]++;
count++;
}
public float GetFrequency(Color c)
{
return 1f * sum[c.R / 8, c.G / 8, c.B / 8] / count;
}
}
}