获取图像的RGB值,并可能在c#中移动图像文件
本文关键字:图像 移动 文件 RGB 获取 | 更新日期: 2023-09-27 18:14:41
我正在考虑在c#中做一个项目,该项目查看图像文件,不确定扩展名,并注意RGB值,如果它太暗,将其移动到另一个文件夹,供我稍后查看
这里是block形式的
从目录加载多个图像>检查每个文件的RGB值>如果太暗>移动到不同的文件夹。如果没有忽略(留在原始文件夹)
我知道基本的,比如从dir获取文件,但检查整个图片的RGB值,然后移动它或忽略它,我被难住了。
我有这样的代码:
private void button1_Click(object sender, EventArgs e)
{
CompareImages(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "checked"), 127.0, new string[] {"*.jpg", "*.png"});
}
private void CompareImages(string sourceFolder, string disposedImgFolder, double threshold, string[] extensions)
{
if (Directory.Exists(sourceFolder))
{
DirectoryInfo dir = new DirectoryInfo(sourceFolder);
List<FileInfo> pictures = new List<FileInfo>();
foreach (string ext in extensions)
{
FileInfo[] fi = dir.GetFiles(ext);
pictures.AddRange(fi);
}
Directory.CreateDirectory(disposedImgFolder);
int j = 0;
if (pictures.Count > 0)
{
for (int i = 0; i < pictures.Count; i++)
{
Image img = null;
Bitmap bmp = null;
try
{
img = Image.FromFile(pictures[i].FullName);
bmp = new Bitmap(img);
img.Dispose();
double avg = GetAveragePixelValue(bmp);
bmp.Dispose();
if (avg < threshold)
{
string dest = Path.Combine(disposedImgFolder, pictures[i].Name);
if (File.Exists(dest) == false)
{
pictures[i].MoveTo(dest);
j++;
}
else
{
}
}
else
{
}
}
catch
{
if (img != null)
img.Dispose();
if (bmp != null)
bmp.Dispose();
}
}
MessageBox.Show("Done, " + j.ToString() + " files moved.");
}
}
}
private unsafe double GetAveragePixelValue(Bitmap bmp)
{
BitmapData bmData = null;
try
{
bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int stride = bmData.Stride;
IntPtr scan0 = bmData.Scan0;
int w = bmData.Width;
int h = bmData.Height;
double sum = 0;
long pixels = bmp.Width * bmp.Height;
byte* p = (byte*)scan0.ToPointer();
for (int y = 0; y < h; y++)
{
p = (byte*)scan0.ToPointer();
p += y * stride;
for (int x = 0; x < w; x++)
{
double i = ((double)p[0] + p[1] + p[2]) / 3.0;
sum += i;
p += 4;
}
}
bmp.UnlockBits(bmData);
double result = sum / (double)pixels;
return result;
}
catch
{
try
{
bmp.UnlockBits(bmData);
}
catch
{
}
}
return -1;
}
如何定义阈值?
如果要读取图像的每个像素,则必须将其转换为位图。然后你可以使用GetPixel方法。但是,这个过程非常缓慢,并且需要大量的CPU。如果您这样做,您真的应该在此之前运行一些测试。
using (var m = new MemoryStream())
{
using (var img = Image.FromFile(args[0]))
{
img.Save(m, ImageFormat.Bmp);
}
m.Position = 0;
using (var bitmap = (Bitmap)Bitmap.FromStream(m))
{
for (var x = 0; x < bitmap.Width; x++)
{
for (var y = 0; y < bitmap.Height; y++)
{
var color = bitmap.GetPixel(x, y);
// TODO: Do what ever you want
}
}
}
}
我认为你需要读一点关于RGB。每个像素都有一个与之相关的红、绿、蓝值,我猜你正在寻找一种方法来测量"平均"像素的亮度?如果是这样,你需要循环遍历所有像素。同时计算每个像素的亮度。每个像素的"亮度"可以用几种方法计算,你可以简单地做(R + G + B)/3,或者你可以尝试模拟人眼对R, G和B的敏感度不一样。
然后你必须决定如何使用像素的"亮度"。Mean, Median,还有什么?这取决于你想做什么。
更新:在阅读了更多你的评论后,我仍然不确定你所说的"明亮"或"黑暗"是什么意思。似乎你的术语有点混乱,你一直在谈论整个图像的RGB值,但图像中的RGB值指的是单个像素值。
我相信这个页面可以帮助你做你想做的事情:http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx同时,一些辅助阅读来理解RGB:
http://en.wikipedia.org/wiki/Luma_(视频)
http://en.wikipedia.org/wiki/RGB_color_space