gpt4 book ai didi

c# - 从 32-BPP 转换为 8-BPP 索引 (C#)

转载 作者:太空狗 更新时间:2023-10-29 21:42:20 25 4
gpt4 key购买 nike

我需要拍摄全彩色 JPG 图像并将其颜色重新映射到索引调色板。调色板将包含从数据库中填充的特定颜色。我需要将图像的每种颜色映射到索引中它的“最接近”值。我确信有不同的算法来比较和计算“最接近”的值。仅查找 C#、.NET 托管代码库。

(它将用于我们有 120 种左右特定颜色的按钮,并且我们希望将任何图像映射到这 120 种颜色以制作拼贴画的过程)。

最佳答案

对 GDI 没有任何帮助。索引图像似乎是一种落后于微软的技术。您所能做的就是读写索引图像文件。

量化图像中的颜色通常有两个步骤:
1)找到图像的最佳调色板(颜色量化)
2) 将源 solors 映射到找到的调色板(颜色映射)

据我了解,您已经在数据库中拥有调色板,这意味着最困难的部分已经为您完成。您需要做的就是将 24 位颜色映射到提供的调色板颜色。如果您没有起始调色板,则必须使用量化算法自行计算:八叉树或中值切割是最著名的。中值切割可提供更好的结果,但实现和微调速度较慢且较难。

要映射颜色,在您的情况下最简单的算法是计算从源颜色到所有调色板颜色的距离并选择最近的颜色。

float ColorDistanceSquared(Color c1, Color c2)
{
float deltaR = c2.R - c1.R;
float deltaG = c2.G - c1.G;
float deltaB = c2.B - c1.B;
return deltaR*deltaR + deltaG*deltaG + deltaB*deltaB;
}

你也可以考虑 channel ,让蓝色的重量更轻,不要太过分,否则会产生可怕的结果,特别是 30/59/11 根本不起作用:

float ColorDistanceSquared(Color c1, Color c2)
{
float deltaR = (c2.R - c1.R) * 3;
float deltaG = (c2.G - c1.G) * 3;
float deltaB = (c2.B - c1.B) * 2;
return deltaR*deltaR + deltaG*deltaG + deltaB*deltaB;
}

为所有源颜色和调色板颜色调用那个东西并找到最小值。如果您在进入 map 时缓存结果,速度会非常快。

此外,源颜色很少适合调色板颜色,以至于不会在图像中产生 strip 和普通区域以及细节丢失。为避免这种情况,您可以使用抖动。最简单的算法和提供最佳结果的算法是误差扩散抖动。

映射颜色后,您必须手动锁定位图并在其中写入索引,因为 .Net 不允许您写入索引图像。

关于c# - 从 32-BPP 转换为 8-BPP 索引 (C#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1684362/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com