也许像这样做会更快。原因是,
Getbits
和
Setbits
非常慢,每次都会内部调用lockbits锁定内存。最好一次性完成所有操作,使用
LockBits
、
unsafe
、
fixed
和
Dictionary
。
为了测试结果,我使用了这张图片:
来源:
我将结果与您的原始版本进行了比较,结果相同。
基准测试
Mode : Release (64Bit)
Test Framework : .NET Framework 4.7.1 (CLR 4.0.30319.42000)
Operating System : Microsoft Windows 10 Pro
Version : 10.0.17134
CPU Name : Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz
Description : Intel64 Family 6 Model 42 Stepping 7
Cores (Threads) : 4 (8) : Architecture : x64
Clock Speed : 3401 MHz : Bus Speed : 100 MHz
L2Cache : 1 MB : L3Cache : 8 MB
测试1
--- Random Set ------------------------------------------------------------
| Value | Average | Fastest | Cycles | Garbage | Test | Gain |
--- Scale 1 ------------------------------------------------ Time 8.894 ---
| Mine1 | 5.211 ms | 4.913 ms | 17.713 M | 0.000 B | Pass | 93.50 % |
| Original | 80.107 ms | 75.131 ms | 272.423 M | 0.000 B | Base | 0.00 % |
---------------------------------------------------------------------------
完整代码
public unsafe byte[] Convert(string input)
{
using (var bmp = new Bitmap(input))
{
var pixels = bmp.Palette.Entries.Select((color, i) => new {x = color,i})
.ToDictionary(arg => arg.x.ToArgb(), x => x.i);
var bits = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb);
var data = new byte[bmp.Height * bmp.Width];
fixed (byte* pData = data)
{
var d = pData;
var length = (int*)bits.Scan0 + bmp.Height * bmp.Width;
for (var p = (int*)bits.Scan0; p < length; p++, d++)
*d = (byte)pixels[*p];
}
bmp.UnlockBits(bits);
return data;
}
}
摘要
我并不是一个图像专家,如果这种方法行不通,那么你的索引图像可能有一些我不理解的不同之处。
更新
要检查像素格式和调色板是否存在,您可以使用以下方法:
bmp.PixelFormat
bmp.Palette.Entries.Any()
更新2
Vlad i Slav 提供的有效解决方案如下:
我需要将 PixelFormat.Format32bppPArgb
替换为 Format32bppArgb
并添加此检查。
if (pixels.ContainsKey(*p))
*d = (byte)pixels[*p];
else
*d = 0;.
此外,需要从调色板中获取不同的值,因为我在那里遇到了一些错误。
data[(i * bitmap.Width) + j] = (byte)pixels[k].IndexOf(bitmap.GetPixel(j, i));
期间会抛出ArgumentOutOfRangeException异常。其次,这种方式写入的数组二进制数据不正确,与我接收到的数据不同。第三,我没有注意到显着的时间差异。 - Vlad i Slav