【发布时间】:2016-02-14 09:43:48
【问题描述】:
我尝试加载 JPEG 文件并从图像中删除所有黑白像素
C#代码:
...
m_SrcImage = new Bitmap(imagePath);
Rectangle r = new Rectangle(0, 0, m_SrcImage.Width, m_SrcImage.Height);
BitmapData bd = m_SrcImage.LockBits(r, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
//Load Colors
int[] colours = new int[m_SrcImage.Width * m_SrcImage.Height];
Marshal.Copy(bd.Scan0, colours, 0, colours.Length);
m_SrcImage.UnlockBits(bd);
int len = colours.Length;
List<Color> result = new List<Color>(len);
for (int i = 0; i < len; ++i)
{
uint w = ((uint)colours[i]) & 0x00FFFFFF; //Delete alpha-channel
if (w != 0x00000000 && w != 0x00FFFFFF) //Check pixel is not black or white
{
w |= 0xFF000000; //Return alpha channel
result.Add(Color.FromArgb((int)w));
}
}
...
之后我尝试通过这段代码在 List 中找到唯一的颜色
result.Sort((a, b) =>
{
return a.R != b.R ? a.R - b.R :
a.G != b.G ? a.G - b.G :
a.B != b.B ? a.B - b.B :
0;
});
List<Color> uniqueColors = new List<Color>( result.Count);
Color rgbTemp = result[0];
for (int i = 0; i < len; ++i)
{
if (rgbTemp == result[i])
{
continue;
}
uniqueColors.Add(rgbTemp);
rgbTemp = result[i];
}
uniqueColors.Add(rgbTemp);
而且这段代码在不同机器上对同一图像产生不同的结果!
例如,在this image 上,它会产生:
- .NET 版本 4 的 XP SP3 上的 43198 种独特颜色
- .NET 4.5 版 Win7 Ultimate 上的 43168 种独特颜色
你可以download here的最小测试项目。它只是打开选定的图像并生成具有独特颜色的 txt 文件。
还有一个事实。某些像素在不同机器上的读取方式不同。我将 txt 文件与 notepad++ 进行比较,结果显示某些像素具有不同的 RGB 分量。每个组件的差为 1,例如
- Win7像素:255 200 100
- WinXP 像素:254 199 99
我看过这篇文章
stackoverflow.com/questions/2419598/why-might-different-computers-calculate-different-arithmetic-results-in-vb-net
(对不起,我没有足够的链接正常链接)。
...但是没有关于如何修复它的信息。
项目是在 VS 2015 社区版中使用 OS Windows 7 的机器上为 .NET 4 客户端配置文件编译的。
【问题讨论】:
-
要上传图片,您应该选择不需要我们登录的免费上传服务
-
@TaW 将图片移至 imgur.com 并将测试项目移至 github
-
谢谢。但是我猜 Lasse 的回答是正确的: JPeg 并不是要以绝对准确度再现图像。如果您真的需要,请转到 PNG!
-
在 gdiplus.dll 版本 1.10 中更改了 JPEG 编解码器。 XP 有 1.00 版。还有更响亮和令人信服的证据表明 XP 确实、真正地结束了。否则,追求像素完美的实际理由太少会导致有损图像格式。它只是不同,继续前进。
-
@HansPassant 我不能使用其他格式。我为其他人写的,他需要JPEG)))