Phi*_*ert 21
最快的方法是使用不安全的代码:
BitmapData srcData = bm.LockBits(
new Rectangle(0, 0, bm.Width, bm.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb);
int stride = srcData.Stride;
IntPtr Scan0 = srcData.Scan0;
long[] totals = new long[] {0,0,0};
int width = bm.Width;
int height = bm.Height;
unsafe
{
byte* p = (byte*) (void*) Scan0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
for (int color = 0; color < 3; color++)
{
int idx = (y*stride) + x*4 + color;
totals[color] += p[idx];
}
}
}
}
int avgB = totals[0] / (width*height);
int avgG = totals[1] / (width*height);
int avgR = totals[2] / (width*height);
Run Code Online (Sandbox Code Playgroud)
小心:我没有测试这段代码......(我可能已经削减了一些角落)
此代码还可以提供32位图像.对于24位图像.将x*4更改为x*3
Loo*_*fer 11
这种事情会起作用,但它可能不够快,不能那么有用.
public static Color getDominantColor(Bitmap bmp)
{
//Used for tally
int r = 0;
int g = 0;
int b = 0;
int total = 0;
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
Color clr = bmp.GetPixel(x, y);
r += clr.R;
g += clr.G;
b += clr.B;
total++;
}
}
//Calculate average
r /= total;
g /= total;
b /= total;
return Color.FromArgb(r, g, b);
}
Run Code Online (Sandbox Code Playgroud)
Mus*_*sis 11
这是一个更简单的方法:
Bitmap bmp = new Bitmap(1, 1);
Bitmap orig = (Bitmap)Bitmap.FromFile("path");
using (Graphics g = Graphics.FromImage(bmp))
{
// updated: the Interpolation mode needs to be set to
// HighQualityBilinear or HighQualityBicubic or this method
// doesn't work at all. With either setting, the results are
// slightly different from the averaging method.
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(orig, new Rectangle(0, 0, 1, 1));
}
Color pixel = bmp.GetPixel(0, 0);
// pixel will contain average values for entire orig Bitmap
byte avgR = pixel.R; // etc.
Run Code Online (Sandbox Code Playgroud)
基本上,您使用DrawImage将原始位图复制到1像素位图.然后,该1个像素的RGB值将表示整个原件的平均值.GetPixel相对较慢,但只有当您在大型Bitmap上逐像素地使用它时才会这样.在这里召唤一次并不重要.
使用LockBits确实很快,但是一些Windows用户具有防止执行"不安全"代码的安全策略.我之所以提到这一点,是因为这个事实最近让我对后面的事情有所了
更新:InterpolationMode设置为HighQualityBicubic,此方法大约需要使用LockBits平均的两倍; 使用HighQualityBilinear,它只需要稍长于LockBits.因此,除非您的用户拥有禁止unsafe代码的安全策略,否则绝对不要使用我的方法.
更新2: 随着时间的推移,我现在意识到为什么这种方法根本不起作用.即使是最高质量的插值算法也只包含几个相邻的像素,因此在不丢失信息的情况下可以压缩多少图像是有限的.无论您使用何种算法,将图像压缩到一个像素都远远超出此限制.
唯一的方法是逐步缩小图像(可能每次缩小一半),直到将其缩小到一个像素的大小.我不能用单词表达完全浪费时间写这样的东西,所以当我想到它时,我很高兴我停了下来.:)
拜托,没有人再投票支持这个答案 - 这可能是我最愚蠢的想法.
| 归档时间: |
|
| 查看次数: |
40546 次 |
| 最近记录: |