XI
xionglongztz/Chromis
🐟 Extract dominant colors from images using K-Means, Median Cut, or Octree algorithms. | 使用K-Means聚类,中位切分或八叉树算法从图像中提取主颜色的类库。
Chromis 🐟
Extract dominant colors from images using K-Means, Median Cut, or Octree algorithms.
Chromis is a lightweight, cross-platform .NET library for color extraction, designed with zero UI dependencies and clean data structures.
✨ Features
- 🎨 Extract dominant colors from images
- ⚡ Multiple algorithms:
- K-Means
- Median Cut
- Octree
- 🧩 Cross-platform (.NET Framework / .NET 6+)
- 🪶 Lightweight and dependency-free public API
- 🔄 Compatible with legacy System.Drawing types (via overloads)
📦 Installation
dotnet add package Chromis🧠 Basic Usage
C#
//.NET Framework
using System;
using System.Collections.Generic;
using System.Drawing;
public List<Color> GetPixelsFromImage(Image image, int stepCount = 5)
{
if (stepCount < 1)
throw new ArgumentOutOfRangeException(nameof(stepCount), "stepCount must be positive");
var pixels = new List<Color>();
using (var bmp = new Bitmap(image))
{
for (int x = 0; x < bmp.Width; x += stepCount)
{
for (int y = 0; y < bmp.Height; y += stepCount)
{
pixels.Add(bmp.GetPixel(x, y));
}
}
}
return pixels;
}
//.NET
using System;
using System.Collections.Generic;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
public List<Rgba64> GetPixelsFromImage(Image image, int stepCount = 5)
{
if (stepCount <= 0)
throw new ArgumentException("stepCount must be positive");
var pixels = new List<Rgba64>();
var rgbaImage = image as Image<Rgba64>;
bool needDispose = false;
if (rgbaImage == null)
{
rgbaImage = image.CloneAs<Rgba64>();
needDispose = true;
}
try
{
var frame = rgbaImage.Frames[0];
for (int y = 0; y < frame.Height; y += stepCount)
{
var row = frame.GetPixelMemoryGroup(y);
for (int x = 0; x < frame.Width; x += stepCount)
{
pixels.Add(row.Span[x]);
}
}
}
finally
{
if (needDispose)
rgbaImage?.Dispose();
}
return pixels;
}Usage
using Chromis;
var sampledColors = GetPixelsFromImage(PictureBox1.Image);
var rgbColors = new List<RGBColor>();
foreach (var color in sampledColors)
{
rgbColors.Add(RGBColor.FromRGB(color.R, color.G, color.B));
}
var colorInfos = ColorExtractor.Extract(rgbColors, 10);
foreach (var ci in colorInfos)
{
Console.WriteLine($"{ci.Color.R}, {ci.Color.G}, {ci.Color.B} - {ci.Ratio:P}");
}VB.NET
'.NET Framework
Imports System;
Imports System.Collections.Generic;
Imports System.Drawing;
Public Function GetPixelsFromImage(image As Image, Optional stepCount As Integer = 5) As List(Of Color)
If stepCount < 1 Then Throw New ArgumentOutOfRangeException(NameOf(stepCount), "stepCount must be positive")
Dim pixels As New List(Of Color)()
Using bmp = New Bitmap(image)
For x = 0 To bmp.Width - 1 Step stepCount
For y = 0 To bmp.Height - 1 Step stepCount
pixels.Add(bmp.GetPixel(x, y))
Next
Next
End Using
Return pixels
End Function
'.NET
Imports SixLabors.ImageSharp
Imports SixLabors.ImageSharp.Advanced
Imports SixLabors.ImageSharp.PixelFormats
Public Function GetPixelsFromImage(image As Image, Optional stepCount As Integer = 5) As List(Of Rgba64)
If stepCount <= 0 Then Throw New ArgumentException("stepCount must be positive")
Dim pixels As New List(Of Rgba64)()
Dim rgbaImage As Image(Of Rgba64) = TryCast(image, Image(Of Rgba64))
Dim needDispose As Boolean = False
If rgbaImage Is Nothing Then
rgbaImage = image.CloneAs(Of Rgba64)()
needDispose = True
End If
Try
Dim frame = rgbaImage.Frames(0)
For y As Integer = 0 To frame.Height - 1 Step stepCount
Dim row = frame.GetPixelMemoryGroup(y)
For x As Integer = 0 To frame.Width - 1 Step stepCount
pixels.Add(row.Span(x))
Next
Next
Finally
If needDispose Then rgbaImage?.Dispose()
End Try
Return pixels
End FunctionUsage
Imports Chromis
Dim pixels As New List(Of ColorExtractor.RGBColor)
For Each sampledColor In GetPixelsFromImage(PictureBox1.Image)
pixels.Add(ColorExtractor.RGBColor.FromRGB(sampledColor.R, sampledColor.G, sampledColor.B))
Next
Dim colorInfos = ColorExtractor.Extract(pixels, 10)
For Each ci In colorInfos
Console.WriteLine($"{ci.Color.R}, {ci.Color.G}, {ci.Color.B} - {ci.Ratio:P}")
NextR,G,B: RGB color values (0 ~ 255)Ratio: Percentage of this color in the image (0 ~ 1)
📊 Algorithms
Chromis supports multiple color quantization algorithms:
- K-Means – balanced and accurate
- Median Cut – fast and classic
- Octree – memory efficient
📄 License
On this page
Contributors
Apache License 2.0
Created March 18, 2026
Updated March 20, 2026
