.NET 中的彩色图像量化

发布于 2024-11-19 11:12:43 字数 212 浏览 2 评论 0原文

我想减少 C# 中位图的唯一颜色的数量。

我想这样做的原因是,最初使用三种颜色创建的图像,但由于许多因素(包括压缩)现在具有超过三种颜色(即相邻像素相互影响)

知道如何做到这一点吗?

该解决方案可能是将整个位图从 RGB 转换为索引颜色系统,或者是一些可以应用于单个像素的函数。

任何 GDI+ 或 Emgu (opencv) 解决方案都适合我。

I want to reduce the number of unique colors of a bitmap in c#.

The reason I want to do this is that an image which is initially created with three color but due to many factors (including compression) has now more than three colors (i.e neighbour pixels has affected each other)

Any idea of how to do that?

The solution maybe something to convert the whole bitmap from RGB to Indexed color system or some function that can be applied to a single pixel.

Any GDI+ or Emgu (opencv) solutions are good for me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

零時差 2024-11-26 11:12:43

请访问 http://nquant.codeplex 查看 nQuant .com。这比 Magnus 引用的 MSDN 文章中的代码质量要高得多。它还考虑了 Alpha 层,而 msdn 文章仅评估 RGB。源代码可用,并且附带 博客文章,详细讨论了代码和算法。

Check out nQuant at http://nquant.codeplex.com. This yields much higher quality than the code in the MSDN article that Magnus references. It also takes the Alpha layer into consideration while the msdn article only evaluates RGB. Source code is available and there is an accompanying blog post that discusses the code and algorithm in detail.

¢好甜 2024-11-26 11:12:43

msdn 上有一篇文章,名为优化 ASP.NET 图像的颜色量化这可能对您有帮助,它有很好的 示例代码

There is an article on msdn called Optimizing Color Quantization for ASP.NET Images that might help you, it has good example code.

东京女 2024-11-26 11:12:43

我刚刚偶然发现了这个问题,虽然这是一个相当老的问题,但也许提到去年我做了我的 绘图库公共(NuGet),它也恰好支持量化。

注意:由于问题包含 GDI+ 标记,因此下面的示例适用于 Bitmap 类型,但该库支持完全托管的位图数据操作它还支持每个平台上的所有像素格式(请参阅BitmapDataFactoryBitmapDataExtensions 类)。

如果您有 Bitmap 实例,则量化如下简单:

using System.Drawing;
using System.Drawing.Imaging;
using KGySoft.Drawing;
using KGySoft.Drawing.Imaging;

// [...]

IQuantizer quantizer = PredefinedColorsQuantizer.FromCustomPalette(myColors, backColor);

// getting a quantized clone of a Bitmap with arbitrary PixelFormat:
Bitmap quantizedBitmap = originalBitmap.ConvertPixelFormat(PixelFormat.Format8bppIndexed,
    quantizer);

// or, you can quantize a Bitmap in-place (which does not change PixelFormat):
originalBitmap.Quantize(quantizer);

原始位图:

原始图像:带有 alpha 渐变的色调

使用自定义 8 色调色板和银色背景的量化位图(在此调色板中显示为白色):

使用自定义 8 调色板和银色背景量化的色调,无抖动。

在上面的示例中,我使用了 FromCustomPalette 方法,但还有许多其他预定义的方法PredefinedColorsQuantizerOptimizedPaletteQuantizer 类(有关图像和代码示例,请参阅成员)。

由于减少颜色可能会严重影响结果的质量,因此您可能需要在量化中使用抖动:

IQuantizer quantizer = PredefinedColorsQuantizer.FromCustomPalette(myColors, backColor);
IDitherer = OrderedDitherer.Bayer8x8;

// ConvertPixelFormat can be used also with a ditherer
Bitmap quantizedBitmap = originalBitmap.ConvertPixelFormat(PixelFormat.Format8bppIndexed,
    quantizer, ditherer);

// Or use the Dither extension method to change the Bitmap in-place
originalBitmap.Dither(quantizer, ditherer);

即使使用相同的颜色,差异也相当显着:

使用自定义 8 调色板和银色背景量化色调,使用Bayer 8x8 抖动

您会在 OrderedDithererErrorDiffusionDitherer, RandomNoiseDithererInterleavedGradientNoiseDitherer 类。

要在应用程序中尝试可能的内置量化器和抖动器,您可以使用我的成像工具 应用程序。在链接中,您还可以找到其源代码,其中提供了一些更高级的示例,包括可取消的异步转换和进度跟踪等。

Changing具有量化和抖动的像素格式

I've just stumbled upon this question and though it is quite an old one maybe it still can be useful to mention that last year I made my Drawing Libraries public (NuGet), which happens to support quantization, too.

Note: As the question contains the GDI+ tag the examples below go for the Bitmap type but the library supports completely managed bitmap data manipulation as well, which supports all pixel formats on every platform (see BitmapDataFactory and BitmapDataExtensions classes).

If you have a Bitmap instance, quantization is as simple as follows:

using System.Drawing;
using System.Drawing.Imaging;
using KGySoft.Drawing;
using KGySoft.Drawing.Imaging;

// [...]

IQuantizer quantizer = PredefinedColorsQuantizer.FromCustomPalette(myColors, backColor);

// getting a quantized clone of a Bitmap with arbitrary PixelFormat:
Bitmap quantizedBitmap = originalBitmap.ConvertPixelFormat(PixelFormat.Format8bppIndexed,
    quantizer);

// or, you can quantize a Bitmap in-place (which does not change PixelFormat):
originalBitmap.Quantize(quantizer);

Original bitmap:

Original image: Color hues with alpha gradient

Quantized bitmap using a custom 8 colors palette and silver background (which appears white with this palette):

Color hues quantized with custom 8 color palette and silver background, no dithering.

In the example above I used the FromCustomPalette method but there are many other predefined quantizers available in the PredefinedColorsQuantizer and OptimizedPaletteQuantizer classes (see the members for image and code examples).

And since reducing colors may severely affect the quality of the result you might want to use dithering with the quantization:

IQuantizer quantizer = PredefinedColorsQuantizer.FromCustomPalette(myColors, backColor);
IDitherer = OrderedDitherer.Bayer8x8;

// ConvertPixelFormat can be used also with a ditherer
Bitmap quantizedBitmap = originalBitmap.ConvertPixelFormat(PixelFormat.Format8bppIndexed,
    quantizer, ditherer);

// Or use the Dither extension method to change the Bitmap in-place
originalBitmap.Dither(quantizer, ditherer);

The difference is quite significant, even though the same colors are used:

Color hues quantized with custom 8 color palette and silver background, using Bayer 8x8 dithering

You will find a lot of image examples in the description of the OrderedDitherer, ErrorDiffusionDitherer, RandomNoiseDitherer and InterleavedGradientNoiseDitherer classes.

To try the possible built-in quantizers and ditherers in an application you can use my Imaging Tools app. In the link you can find also its source, which provides a bit more advanced examples with cancellable async conversions with progress tracking, etc.

Changing Pixel Format with Quantizing and Dithering

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文