Skip to content

Latest commit

 

History

History
131 lines (104 loc) · 3.75 KB

README.md

File metadata and controls

131 lines (104 loc) · 3.75 KB

Icon

Vibrancy

Extract prominent colours from images

Build NuGet

Overview

Provides basic colour extraction from images into "swatches". As configured by a SwatchDefinition, each swatch has a min/max/target saturation an value (see HSV). To avoid extracting too many similar colours, a CIELAB-based perception comparison is performed using a minimum colour threshold (via PaletteOptions, default: 25).

The extraction process is computationally intensive as it processes every individual pixel in an image. It is highly recommended resizing large images before running GetSwatches and avoiding setting MinimumColorThreshold too low. The smaller the image, the less colours will be able to be extracted.

Powered by ImageSharp.

Results

Input image (640x426)

Output (default settings, rendered to an image)

Columns represent swatch definitions (Dark Vibrant, Vibrant, Light Vibrant, Dark Muted, Muted, Light Muted). Rows represent the colours found in each.

Swatch Definitions

There are 6 built-in swatch definitions:

  • Dark Vibrant
  • Vibrant
  • Light Vibrant
  • Dark Muted
  • Muted
  • Light Muted

While these are likely suitable for most applications, you can create your own swatch definitions too:

new SwatchDefinition("My Swatch Definition", MinSaturation: 0.55f, TargetSaturation: 1, MinValue: 0.1f, TargetValue: 0.3f, MaxValue: 0.64f);

Usage

Simple Usage

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using TurnerSoftware.Vibrancy;

var palette = new Palette(new PaletteOptions(new[]
{
	SwatchDefinition.DarkVibrant,
	SwatchDefinition.Vibrant,
	SwatchDefinition.LightVibrant,
	SwatchDefinition.DarkMuted,
	SwatchDefinition.Muted,
	SwatchDefinition.LightMuted
}));

var image = await Image.LoadAsync<Rgb24>("path/to/image.jpg");
image.Mutate(x => {
	x.Resize(200, 0);
});
var swatches = palette.GetSwatches(image);

var darkVibrantSwatch = swatches[0];
foreach (var swatchColor in vibrantSwatch.GetColors())
{
	var rgb = swatchColor.Rgb;
	//Your per-colour processing goes here
}

Creating the example output

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using TurnerSoftware.Vibrancy;

var palette = new Palette(new PaletteOptions(new[]
{
	SwatchDefinition.DarkVibrant,
	SwatchDefinition.Vibrant,
	SwatchDefinition.LightVibrant,
	SwatchDefinition.DarkMuted,
	SwatchDefinition.Muted,
	SwatchDefinition.LightMuted
}));

var file = "path/to/image.jpg";
var image = await Image.LoadAsync<Rgb24>(file);
var swatches = palette.GetSwatches(image);

var outputImage = new Image<Rgba32>(swatches.Count, swatches.Max(s => s.Count));
outputImage.Mutate(x =>
{
	x.BackgroundColor(Color.Transparent);
});
for (var x = 0; x < swatches.Count; x++)
{
	var swatch = swatches[x];
	var colours = swatch.GetColors()
		.OrderByDescending(c => (int)(c.Hsv.V * 3))
		.ThenByDescending(c => (int)(c.Hsv.S * 3))
		.ThenBy(c => c.Hsv.H)
		.ToArray();
	for (var y = 0; y < colours.Length; y++)
	{
		outputImage[x, y] = colours[y].Rgb;
	}
}
outputImage.Mutate(x =>
{
	x.Resize(swatches.Count * 20, 0, new NearestNeighborResampler());
});
await outputImage.SaveAsPngAsync($"output-{Path.GetFileNameWithoutExtension(file)}.png");