FrameworkExtensions.System.Drawing 1.0.0.112

There is a newer version of this package available.
See the version list below for details.
dotnet add package FrameworkExtensions.System.Drawing --version 1.0.0.112
                    
NuGet\Install-Package FrameworkExtensions.System.Drawing -Version 1.0.0.112
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FrameworkExtensions.System.Drawing" Version="1.0.0.112" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FrameworkExtensions.System.Drawing" Version="1.0.0.112" />
                    
Directory.Packages.props
<PackageReference Include="FrameworkExtensions.System.Drawing" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FrameworkExtensions.System.Drawing --version 1.0.0.112
                    
#r "nuget: FrameworkExtensions.System.Drawing, 1.0.0.112"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FrameworkExtensions.System.Drawing@1.0.0.112
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FrameworkExtensions.System.Drawing&version=1.0.0.112
                    
Install as a Cake Addin
#tool nuget:?package=FrameworkExtensions.System.Drawing&version=1.0.0.112
                    
Install as a Cake Tool

Extensions to System.Drawing

Build Tests

Last Commit NuGet Version License

Extension methods for System.Drawing types (bitmaps, images, colors, graphics).


Extension Methods

Bitmap Extensions (Bitmap)

Bitmap Locking
  • Lock(...) - Lock bitmap for direct pixel access (8 overloads for different combinations)
    • Lock() - Lock entire bitmap with ReadWrite mode
    • Lock(Rectangle) - Lock region
    • Lock(ImageLockMode) - Lock with specific mode
    • Lock(PixelFormat) - Lock with specific format
    • Lock(Rectangle, ImageLockMode)
    • Lock(Rectangle, PixelFormat)
    • Lock(ImageLockMode, PixelFormat)
    • Lock(Rectangle, ImageLockMode, PixelFormat) - Full control
    • Returns format-specific IBitmapLocker implementation
Transformations
  • ConvertPixelFormat(PixelFormat) - Convert bitmap to different pixel format
  • Crop(Rectangle, PixelFormat = DontCare) - Extract region from bitmap
  • Resize(int width, int height, InterpolationMode = Bicubic) - Resize bitmap
  • Rotated(float angle, Point? center = null) - Create rotated copy of bitmap
  • RotateInplace(float angle, Point? center = null) - Rotate bitmap in-place
  • RotateTo(Bitmap target, float angle, Point? center = null) - Rotate to target bitmap
Color Quantization & Dithering
  • ReduceColors<TQuantizer, TDitherer>(quantizer, ditherer, colorCount, isHighQuality) - Reduce image to indexed palette
    • Returns indexed bitmap (1bpp for 2 colors, 4bpp for ≤16, 8bpp for ≤256)
    • isHighQuality: true uses OkLab perceptual color space (slower, better gradients)
    • isHighQuality: false uses linear RGB with Euclidean distance (faster)
using var original = new Bitmap("photo.png");

// High quality: OkLab color space, Floyd-Steinberg dithering
using var indexed = original.ReduceColors(
    new WuQuantizer(),
    ErrorDiffusion.FloydSteinberg,
    16,
    isHighQuality: true);

// Fast: Linear RGB, serpentine dithering
using var fast = original.ReduceColors(
    new OctreeQuantizer(),
    ErrorDiffusion.Atkinson.Serpentine,
    256,
    isHighQuality: false);

indexed.Save("indexed.gif");

Image Extensions (Image)

Multi-Page Support
  • GetPageAt(int page) - Get specific page from multi-page image (e.g., TIFF)
  • GetPageCount() - Get total number of pages in image
Save Operations
  • SaveToPng(FileInfo/string) - Save image as PNG
  • SaveToTiff(string) - Save image as TIFF
  • SaveToJpeg(string/Stream, double quality = 1) - Save as JPEG with quality (0.0-1.0)
Conversions
  • ToIcon(int targetRes = 0) - Convert image to Icon
  • ToBase64DataUri() - Convert to Base64 data URI string
  • FromBase64DataUri(string) (static-like extension on string) - Create image from Base64 data URI
Image Processing
  • MakeGrayscale() - Convert image to grayscale
  • Threshold(byte threshold = 127) - Apply threshold filter (black/white)
  • ApplyPixelProcessor(Func<Color, Color> processor) - Apply custom pixel transformation function
  • MirrorAlongX() - Mirror horizontally
  • MirrorAlongY() - Mirror vertically
  • Resize(int longSide) - Resize to fit within square, keep aspect
  • Resize(int longSide, Color fillColor) - Resize with fill color
  • Resize(int width, int height, bool keepAspect = true, Color? fillColor = null) - Resize with options
  • Resize(int width = -1, int height = -1, InterpolationMode = Default) - Resize with interpolation
  • Rotate(float angle) - Rotate image by angle
  • GetRectangle(Rectangle) - Extract rectangular region
  • ReplaceColorWithTransparency(Color) - Replace specific color with transparency

Color Extensions (Color)

Color Space Conversion
  • Rgb / RgbNormalized - Convert to RGB color space
  • Hsl / HslNormalized - Convert to HSL (Hue, Saturation, Lightness)
  • Hsv / HsvNormalized - Convert to HSV (Hue, Saturation, Value)
  • Hwb / HwbNormalized - Convert to HWB (Hue, Whiteness, Blackness)
  • Cmyk / CmykNormalized - Convert to CMYK (Cyan, Magenta, Yellow, Key)
  • Xyz / XyzNormalized - Convert to CIE XYZ tristimulus values
  • Lab / LabNormalized - Convert to CIE Lab* perceptual color space
  • Yuv / YuvNormalized - Convert to YUV (Luma + chrominance)
  • YCbCr / YCbCrNormalized - Convert to YCbCr digital video encoding
  • Din99 / Din99Normalized - Convert to DIN99 (DIN 6176) perceptual space
Color Comparison
  • IsLike(Color other, byte luminanceDelta = 24, byte chromaUDelta = 7, byte chromaVDelta = 6) - Compare colors in YUV space with tolerance
  • IsLikeNaive(Color other, int tolerance = 2) - Simple RGB comparison with tolerance
Color Blending
  • BlendWith(Color other, float current, float max) - Interpolate between two colors

Graphics Extensions (Graphics)

  • DrawString(float x, float y, string text, Font font, Brush brush, ContentAlignment anchor) - Draw text with anchor positioning
  • DrawCross(float/int x, float/int y, float/int size, Pen pen) - Draw cross marker (4 overloads including Point/PointF)
  • DrawCircle(Pen pen, float centerX, float centerY, float radius) - Draw circle outline
  • FillCircle(Brush brush, float centerX, float centerY, float radius) - Draw filled circle

Rectangle Extensions (Rectangle)

  • MultiplyBy(int factor) - Scale rectangle uniformly
  • MultiplyBy(int xfactor, int yfactor) - Scale rectangle with different X/Y factors
  • CollidesWith(Rectangle/RectangleF) - Check rectangle collision
  • CollidesWith(Point/PointF) - Check if point is inside
  • CollidesWith(int x, int y) / CollidesWith(float x, float y) - Check if coordinates are inside
  • Center() - Get center point
  • SetLeft/SetRight/SetTop/SetBottom(int) - Create new rectangle with modified edge

RectangleF Extensions (RectangleF)

(Similar methods to Rectangle, for floating-point rectangles)


Size Extensions (Size)

  • Center() - Get center point

Point Extensions (Point)

(Generated from T4 template - numeric operations on points)


FileInfo Extensions (FileInfo)

  • GetIcon(bool smallIcon = false, bool linkOverlay = false) - Get Windows shell icon for file
    • Uses native SHGetFileInfo API

Custom Types

IBitmapLocker Interface

Format-specific bitmap pixel access implementations providing optimized read/write access to bitmap data. The correct locker is automatically selected based on the bitmap's pixel format when calling Lock().

Locker Pixel Format Bits Description
Argb16161616BitmapLocker Format64bppArgb 64 High dynamic range ARGB (16 bits/channel)
Argb1555BitmapLocker Format16bppArgb1555 16 1-bit alpha + 5 bits RGB
Argb8888BitmapLocker Format32bppArgb 32 Standard 32-bit ARGB (8 bits/channel)
Gray16BitmapLocker Format16bppGrayScale 16 16-bit grayscale
Indexed1BitmapLocker Format1bppIndexed 1 Monochrome indexed (2 colors)
Indexed4BitmapLocker Format4bppIndexed 4 16-color indexed
Indexed8BitmapLocker Format8bppIndexed 8 256-color indexed
PArgb16161616BitmapLocker Format64bppPArgb 64 Premultiplied alpha 64-bit
PArgb8888BitmapLocker Format32bppPArgb 32 Premultiplied alpha 32-bit
Rgb161616BitmapLocker Format48bppRgb 48 High dynamic range RGB (16 bits/channel)
Rgb555BitmapLocker Format16bppRgb555 16 5 bits per RGB channel
Rgb565BitmapLocker Format16bppRgb565 16 5-6-5 bits RGB
Rgb888BitmapLocker Format24bppRgb 24 Standard 24-bit RGB
Rgb888XBitmapLocker Format32bppRgb 32 24-bit RGB with padding byte
SubRegionBitmapLocker Any - Wraps another locker for sub-region access
UnsupportedDrawingBitmapLocker Other - Fallback using GetPixel/SetPixel

Each locker provides:

  • Direct pointer access to pixel data via BitmapData
  • Indexed pixel access via this[x, y]
  • Fast GetPixelBgra8888() and SetPixelBgra8888() methods
  • Automatic disposal via IDisposable

Color Spaces (System.Drawing.ColorSpaces)

A comprehensive color space conversion and comparison library with zero-cost generic abstractions.

Color Space Types

Type Components Description
Cmyk / CmykNormalized C, M, Y, K Subtractive printing model
Din99 / Din99Normalized L, a, b DIN 6176 perceptual space
Hsl / HslNormalized H, S, L Hue, Saturation, Lightness
Hsv / HsvNormalized H, S, V Hue, Saturation, Value
Hwb / HwbNormalized H, W, B Hue, Whiteness, Blackness
Lab / LabNormalized L, a, b CIE Lab* perceptual color space
Rgb / RgbNormalized R, G, B Standard RGB color model
Xyz / XyzNormalized X, Y, Z CIE XYZ tristimulus values
YCbCr / YCbCrNormalized Y, Cb, Cr Digital video color encoding
Yuv / YuvNormalized Y, U, V Luma + chrominance (PAL/NTSC)

Distance Calculators (Hawkynt.ColorProcessing.Metrics)

Color metrics implementing IColorMetric<T> for palette lookups, quantization, and color comparison.

Generic Metrics
Calculator Color Space Squared Variant Description
Euclidean3F<TKey> Any 3-component float EuclideanSquared3F<TKey> $\sqrt{\Delta c_1^2 + \Delta c_2^2 + \Delta c_3^2}$
Euclidean4F<TKey> Any 4-component float EuclideanSquared4F<TKey> $\sqrt{\Delta c_1^2 + \Delta c_2^2 + \Delta c_3^2 + \Delta c_4^2}$
Euclidean3B<TKey> Any 3-component byte EuclideanSquared3B<TKey> Byte version (0-255 per channel)
Euclidean4B<TKey> Any 4-component byte EuclideanSquared4B<TKey> Byte version with alpha
Chebyshev3F<TKey> Any 3-component float - $\max(\lvert\Delta c_1\rvert, \lvert\Delta c_2\rvert, \lvert\Delta c_3\rvert)$
Chebyshev4F<TKey> Any 4-component float - $\max(\lvert\Delta c_1\rvert, \lvert\Delta c_2\rvert, \lvert\Delta c_3\rvert, \lvert\Delta c_4\rvert)$
Chebyshev3B<TKey> Any 3-component byte - Byte version
Chebyshev4B<TKey> Any 4-component byte - Byte version with alpha
Manhattan3F<TKey> Any 3-component float - $\lvert\Delta c_1\rvert + \lvert\Delta c_2\rvert + \lvert\Delta c_3\rvert$
Manhattan4F<TKey> Any 4-component float - $\lvert\Delta c_1\rvert + \lvert\Delta c_2\rvert + \lvert\Delta c_3\rvert + \lvert\Delta c_4\rvert$
Weighted Metrics
Calculator Squared Variant Description
WeightedEuclidean3F<TKey> WeightedEuclideanSquared3F<TKey> $\sqrt{w_1 \Delta c_1^2 + w_2 \Delta c_2^2 + w_3 \Delta c_3^2}$
WeightedEuclidean4F<TKey> WeightedEuclideanSquared4F<TKey> $\sqrt{w_1 \Delta c_1^2 + w_2 \Delta c_2^2 + w_3 \Delta c_3^2 + w_4 \Delta c_4^2}$
WeightedChebyshev3F<TKey> - $\max(w_1\lvert\Delta c_1\rvert, w_2\lvert\Delta c_2\rvert, w_3\lvert\Delta c_3\rvert)$
WeightedManhattan3F<TKey> - $w_1\lvert\Delta c_1\rvert + w_2\lvert\Delta c_2\rvert + w_3\lvert\Delta c_3\rvert$
Perceptual Lab Metrics (Hawkynt.ColorProcessing.Metrics.Lab)
Calculator Squared Variant Reference Description
CIE76 CIE76Squared CIE 1976 $\Delta E^*_{ab}$ - Euclidean in Lab space
CIE94 CIE94Squared CIE 1994 Improved perceptual formula with weighting
CIEDE2000 CIEDE2000Squared CIE 2000 Most accurate perceptual $\Delta E$
CMC - BS 6923 Textile industry (l=1, c=1)
DIN99Distance - DIN 6176 German industrial standard
RGB-Specific Metrics (Hawkynt.ColorProcessing.Metrics.Rgb)
Calculator Squared Variant Reference Description
CompuPhase CompuPhaseSquared Redmean Weighted RGB approximation using mean red
PngQuant PngQuantSquared pngquant Considers blending on black/white backgrounds
Equality Comparators
Comparator Description
ExactEquality<TKey> Exact bit-level match only
ThresholdEquality<TKey> Match within configurable tolerance

Note: Squared variants are faster (no sqrt) when only relative comparison is needed.

Palette Lookup

The PaletteLookup<TWork, TMetric> struct provides efficient nearest-neighbor color matching with automatic caching.

Members
Member Type Description
Count int Number of colors in the palette
this[int index] TWork Get palette color at index
FindNearest(in TWork color) int Find index of nearest palette color
FindNearestColor(in TWork color) TWork Find nearest palette color directly
FindNearest(in TWork color, out TWork nearest) int Get both index and nearest color
Usage
using Hawkynt.ColorProcessing;
using Hawkynt.ColorProcessing.Metrics;
using Hawkynt.ColorProcessing.Working;

// Create palette lookup with a metric
var lookup = new PaletteLookup<LinearRgbaF, EuclideanSquared4F<LinearRgbaF>>(
    workPalette,
    default);

// Get palette size
int paletteSize = lookup.Count;

// Access palette colors directly
LinearRgbaF firstColor = lookup[0];

// Find nearest by index
int index = lookup.FindNearest(targetColor);

// Find nearest color directly
LinearRgbaF nearest = lookup.FindNearestColor(targetColor);

// Get both index and color in one call
int idx = lookup.FindNearest(targetColor, out LinearRgbaF nearestColor);

// Efficient batch processing - results are cached automatically
foreach (var pixel in imagePixels) {
  var paletteIndex = lookup.FindNearest(pixel);  // O(1) for repeated colors
}

// Using different metrics
var labLookup = new PaletteLookup<LabF, CIEDE2000>(labPalette, default);
var rgbLookup = new PaletteLookup<LinearRgbF, CompuPhaseSquared>(rgbPalette, default);

Color Interpolation (System.Drawing.ColorSpaces.Interpolation)

Type Description
CircularHueLerp<T> Hue-aware interpolation for HSL/HSV/HWB
ColorGradient<T> Multi-stop gradient with configurable interpolation
ColorLerp<T> Linear interpolation in any 3-component color space
ColorLerp4<T> Linear interpolation in 4-component spaces (CMYK)
using System.Drawing.ColorSpaces.Interpolation;

// Interpolate in perceptual Lab space
var lerp = new ColorLerp<Lab>();
var midpoint = lerp.Lerp(color1, color2, 0.5f);

// Create smooth gradients
var gradient = new ColorGradient<Hsl>(Color.Red, Color.Blue);
var colors = gradient.GetColors(10);  // 10 evenly-spaced colors

Color Quantization

Quantizers reduce the number of colors in an image to generate optimized palettes. They analyze color distribution and select representative colors that best preserve visual quality.

Adaptive Quantizers

Adaptive quantizers analyze the image to generate an optimal palette for each specific image.

Quantizer Author Year Type Reference
PngQuantQuantizer Kornel Lesiński 2009 Hybrid pngquant algorithm
WuQuantizer Xiaolin Wu 1991 Variance Graphics Gems II
MedianCutQuantizer Paul Heckbert 1982 Splitting SIGGRAPH '82
OctreeQuantizer Gervautz, Purgathofer 1988 Tree Graphics Gems
NeuquantQuantizer Anthony Dekker 1994 Neural Network: Computing
KMeansQuantizer J. MacQueen 1967 Clustering K-means++
BisectingKMeansQuantizer M. Steinbach et al. 2000 Clustering Bisecting K-Means
IncrementalKMeansQuantizer - - Clustering Online K-Means
GaussianMixtureQuantizer Various 1977 Clustering EM Algorithm
ColorQuantizationNetworkQuantizer Various 1992 Neural LVQ
AduQuantizer - - Clustering Competitive learning
VarianceBasedQuantizer - - Variance Weighted variance optimization
VarianceCutQuantizer - - Variance Maximum variance splitting
BinarySplittingQuantizer - - Splitting Principal axis splitting
SpatialColorQuantizer - - Spatial Simulated annealing
FuzzyCMeansQuantizer J.C. Bezdek 1981 Clustering Pattern Recognition. Ref
PopularityQuantizer - - Histogram Most frequent colors
UniformQuantizer - - Fixed Uniform RGB grid
HierarchicalCompetitiveLearningQuantizer P. Scheunders 1997 Clustering Hierarchical CL - initialization-independent progressive splitting
GeneticCMeansQuantizer P. Scheunders 1997 Clustering Genetic Algorithm + C-Means - global optimization avoids local optima
EnhancedOctreeQuantizer D.S. Bloomberg 2008 Tree Enhanced Octree - variance tracking, adaptive thresholds
OctreeSomQuantizer Park, Kim, Cha 2015 Neural Octree-SOM - two-rate learning reduces color loss
HuffmanQuantizer - - Clustering Huffman-inspired bottom-up merging - preserves dominant colors exactly
Quantizer Parameters
Quantizer Parameter Type Default Range Description
PngQuantQuantizer MedianCutIterations int 3 1-10 Median Cut passes with weight adjustment
KMeansIterations int 10 1-100 K-means/Voronoi refinement iterations
ConvergenceThreshold float 0.0001f 0.00001-0.01 K-means convergence threshold
ErrorBoostFactor float 2.0f 1-5 Weight boost for underrepresented colors
KMeansQuantizer MaxIterations int 100 10-1000 Maximum clustering iterations
ConvergenceThreshold float 0.001f 0.0001-0.1 Stop when centroids move less than this
BisectingKMeansQuantizer MaxIterationsPerSplit int 10 1-50 K-means iterations per bisection
BisectionTrials int 3 1-10 Trials per split (keeps best result)
ConvergenceThreshold float 0.001f 0.0001-0.1 Stop when centroids move less than this
IncrementalKMeansQuantizer RefinementPasses int 3 0-10 Additional refinement passes after initial
GaussianMixtureQuantizer MaxIterations int 50 10-500 Maximum EM iterations
ConvergenceThreshold float 0.0001f 0.00001-0.01 Log-likelihood convergence threshold
MinVariance float 0.0001f 0.00001-0.01 Minimum variance (prevents singular matrices)
MaxSampleSize int 10000 1000-100000 Maximum histogram entries to process
ColorQuantizationNetworkQuantizer MaxEpochs int 100 10-500 Training epochs
InitialLearningRate float 0.3f 0.01-1.0 Initial learning rate
ConscienceFactor float 0.1f 0-1 Balanced neuron usage factor
UseFrequencySensitive bool true - Enable frequency-sensitive learning
MaxSampleSize int 10000 1000-100000 Maximum histogram entries to process
AduQuantizer IterationCount int 10 1-100 Competitive learning iterations
NeuquantQuantizer MaxIterations int 100 1-1000 Network training iterations
InitialAlpha float 0.1f 0.01-1.0 Initial learning rate
SpatialColorQuantizer MaxIterations int 100 10-500 Annealing iterations
SpatialWeight float 0.5f 0-1 Weight for spatial coherence
InitialTemperature float 1.0f 0.1-10 Starting annealing temperature
FuzzyCMeansQuantizer MaxIterations int 100 10-500 Clustering iterations
Fuzziness float 2.0f 1.1-5 Cluster overlap (higher = softer)
MaxSampleSize int 10000 1000-100000 Maximum histogram entries to process
HierarchicalCompetitiveLearningQuantizer EpochsPerSplit int 5 1-20 CL training epochs after each cluster split
InitialLearningRate float 0.1f 0.01-0.5 Initial learning rate for CL
MaxSampleSize int 8192 1000-100000 Maximum histogram entries to process
GeneticCMeansQuantizer PopulationSize int 20 10-100 Number of candidate palettes
Generations int 50 10-500 Number of generations to evolve
TournamentSize int 3 2-10 Tournament selection size
MutationSigma float 10.0f 1-50 Gaussian mutation standard deviation
EliteCount int 2 0-10 Elite individuals preserved each generation
CMeansIterationsPerOffspring int 3 1-10 C-Means iterations per offspring
MaxSampleSize int 10000 1000-100000 Maximum histogram entries to process
EnhancedOctreeQuantizer MaxLevel int 5 3-7 Tree depth (2^level max leaves)
ReservedLevel2Colors int 64 0-128 Colors reserved at level 2 for coverage
OctreeSomQuantizer MaxEpochs int 50 10-200 SOM training epochs
WinnerLearningRate float 0.1f 0.01-0.5 Learning rate for BMU
NeighborLearningRate float 0.001f 0.0001-0.01 Learning rate for neighbors (1% of winner)
MaxSampleSize int 8192 1000-100000 Maximum histogram entries to process
HuffmanQuantizer CandidatesToExamine int 20 5-100 Top candidates for merge selection
SimilarityWeight float 10000.0f 100-100000 Balance frequency vs. similarity in merge

Quantizer Wrappers

Wrappers that enhance other quantizers by applying additional preprocessing or post-processing. Wrappers can be chained for combined effects.

Preprocessing Wrappers
Wrapper Description
PcaQuantizerWrapper Transforms colors to PCA-aligned space before quantization. Ref
BitReductionWrapper Reduces color precision by masking off LSBs, creating posterized/retro effects and faster quantization
Postprocessing Wrappers
Wrapper Description
KMeansRefinementWrapper Refines any quantizer's output using iterative K-means-style clustering. Ref
AcoRefinementWrapper Refines palette using Ant Colony Optimization for escaping local optima. Ref
Wrapper Parameters
Wrapper Parameter Type Default Range Description
BitReductionWrapper bitsToRemove int 1 1-7 LSBs to mask off per component (1=128 levels)
KMeansRefinementWrapper iterations int 10 1-100 K-means refinement iterations
AcoRefinementWrapper antCount int 20 1-100 Number of ants exploring solutions
iterations int 50 1-500 ACO iterations
evaporationRate double 0.1 0.0-1.0 Pheromone evaporation rate
seed int? null - Random seed for reproducibility
// Wrap a quantizer with PCA preprocessing
var pcaEnhanced = new PcaQuantizerWrapper<WuQuantizer>(new WuQuantizer());

// Add K-means refinement to any quantizer
var refined = new KMeansRefinementWrapper<MedianCutQuantizer>(new MedianCutQuantizer(), iterations: 10);

// Use ACO for complex color distributions (slower but may escape local optima)
var acoRefined = new AcoRefinementWrapper<OctreeQuantizer>(
  new OctreeQuantizer(),
  antCount: 20,
  iterations: 50,
  seed: 42  // for reproducible results
);

// Reduce color precision for retro/posterized effects (4 bits removed = 16 levels per channel)
var posterized = new BitReductionWrapper<MedianCutQuantizer>(new MedianCutQuantizer(), bitsToRemove: 4);

// Chain wrappers for combined effects: BitReduction → KMeans → PCA → Octree
var chained = new BitReductionWrapper<KMeansRefinementWrapper<PcaQuantizerWrapper<OctreeQuantizer>>>(
  new KMeansRefinementWrapper<PcaQuantizerWrapper<OctreeQuantizer>>(
    new PcaQuantizerWrapper<OctreeQuantizer>(new OctreeQuantizer()),
    iterations: 5),
  bitsToRemove: 2
);

Fixed Palette Quantizers

Fixed palette quantizers use predefined color palettes for specific platforms or standards.

Quantizer Colors Use Case Description
WebSafeQuantizer 216 Web graphics Browser-safe web palette
Ega16Quantizer 16 Retro DOS IBM EGA 16-color palette
Vga256Quantizer 256 Retro DOS VGA default 256-color palette
Cga4Quantizer 4 Retro DOS 6 CGA palettes: Palette0 (Green/Red/Brown), Palette1 (Cyan/Magenta/White), Mode5 (Cyan/Red/White) - each with Low/High intensity
Mac8BitQuantizer 256 Retro Mac Classic Macintosh system palette
MonochromeQuantizer 2 B&W Black and white only
GrayscaleQuantizer 2-256 Grayscale Grayscale ramp
CustomPaletteQuantizer Any Custom User-defined palette

Quantizer Usage

using Hawkynt.ColorProcessing.Quantization;

// Generate palette from colors
var quantizer = new WuQuantizer();
Bgra8888[] palette = quantizer.GeneratePalette(colors, 16);

// Generate from histogram (weighted by frequency)
var histogram = new List<(Bgra8888 color, uint count)> { ... };
Bgra8888[] palette = quantizer.GeneratePalette(histogram, 256);

// Fixed palette
var egaPalette = new Ega16Quantizer().GetPalette();

// Reduce colors with quantization
using var reduced = bitmap.ReduceColors(new WuQuantizer(), ErrorDiffusion.FloydSteinberg, 16);

// High-quality PngQuant-style quantization (variance median cut + K-means refinement)
var pngQuant = new PngQuantQuantizer {
  MedianCutIterations = 3,    // Iterations with weight adjustment for underrepresented colors
  KMeansIterations = 10,      // Voronoi/K-means refinement passes
  ErrorBoostFactor = 2.0f     // Boost for poorly quantized colors
};
using var pngResult = bitmap.ReduceColors(pngQuant, ErrorDiffusion.FloydSteinberg, 256);

K-Means Color Metrics

The KMeansQuantizer supports any IColorMetric<Bgra8888> for clustering. See Color Metrics for all available metrics.

// Default K-Means (squared Euclidean - fastest)
var kmeans = new KMeansQuantizer();

// With perceptual Lab-based distance
var perceptual = new KMeansQuantizer<CIEDE2000>();

// With weighted RGB perception
var weighted = new KMeansQuantizer<PngQuantDistance>(default);

// With custom iterations
var custom = new KMeansQuantizer { MaxIterations = 200, ConvergenceThreshold = 0.0001f };

Dithering

Error diffusion dithering distributes quantization error to neighboring pixels for smoother gradients.

Error-Diffusion Ditherers

Ditherer Author Year Neighbors Reference
Atkinson Bill Atkinson 1984 6 Apple MacPaint, 75% error diffusion. Ref
JarvisJudiceNinke J.F. Jarvis, C.N. Judice, W.H. Ninke 1976 12 CGIP vol. 5. Ref
Pigeon Steven Pigeon 2013 7 Blog post with analysis. Ref
ShiauFan J.N. Shiau, Z. Fan 1993 4 US Patent 5,353,127. Ref
ShiauFan2 J.N. Shiau, Z. Fan 1993 5 US Patent 5,353,127. Ref
StevensonArce R.L. Stevenson, G.R. Arce 1985 12 JOSA A vol. 2. Ref
Stucki P. Stucki 1981 12 IBM Research RZ1060. Ref
Burkes D. Burkes 1988 7 CIS Graphics Support Forum, LIB 15. Ref
Diagonal - - 1 Single diagonal neighbor
Diamond - - 8 Symmetric diamond pattern
DoubleDown - - 3 Two rows down
Down - - 1 Single pixel below
EqualFloydSteinberg - - 4 Equal weight distribution variant
FalseFloydSteinberg - - 3 Simplified 3-neighbor variant
Fan93 Z. Fan 1992 4 SPIE'92, "A Simple Modification of Error Diffusion Weights"
FloydSteinberg R.W. Floyd, L. Steinberg 1976 4 Proc. SID vol. 17, "An Adaptive Algorithm for Spatial Greyscale"
HorizontalDiamond - - 6 Diamond with horizontal bias
Sierra Frankie Sierra 1989 10 Three-line filter, King's Quest era
SierraLite Frankie Sierra 1990 3 Filter Lite - minimal variant
Simple - - 1 Single neighbor diffusion
TwoD - - 2 Simple 2-neighbor
TwoRowSierra Frankie Sierra 1990 7 Two-row variant
VerticalDiamond - - 8 Diamond with vertical bias

Ordered Dithering

Ordered dithering uses threshold matrices to determine pixel output. Unlike error diffusion, pixels can be processed independently (parallelizable).

Ditherer Author Year Size Description
Bayer2x2 Bryce Bayer 1973 2×2 Smallest Bayer threshold matrix
Bayer4x4 Bryce Bayer 1973 4×4 Standard Bayer threshold matrix
Bayer8x8 Bryce Bayer 1973 8×8 Large Bayer matrix (256 levels)
Bayer16x16 Bryce Bayer 1973 16×16 Very large Bayer matrix
ClusterDot4x4 - - 4×4 Clustered dot pattern for smoother appearance
ClusterDot8x8 - - 8×8 Larger cluster dot pattern
Diagonal4x4 - - 4×4 Diagonal line pattern
Halftone4x4 - - 4×4 Simulates halftone printing
Halftone8x8 - - 8×8 Larger halftone pattern
// Ordered dithering with Bayer matrix
var ditherer = OrderedDitherer.Bayer8x8;

// Adjust strength (0.0 - 1.0)
var reduced = OrderedDitherer.Bayer4x4.WithStrength(0.5f);

Noise Dithering

Noise dithering adds random or pseudo-random thresholds before quantization. Can be processed in parallel.

Ditherer Description
WhiteNoise Uniform random threshold with equal energy at all frequencies
BlueNoise Spatially-filtered noise with reduced low-frequency content
PinkNoise 1/f noise, equal energy per octave, more natural-looking
BrownNoise 1/f² noise (Brownian motion), strong low-frequency, smooth organic
VioletNoise f noise, high-frequency emphasis, sharp textured appearance
GreyNoise Perceptually uniform noise adjusted for human vision response
InterleavedGradientNoise Deterministic pseudo-random noise for temporal AA. Ref
// Noise dithering
var ditherer = NoiseDitherer.BlueNoise;

// Other noise types
var pink = NoiseDitherer.PinkNoise;     // More natural than white
var brown = NoiseDitherer.BrownNoise;   // Smooth, organic appearance
var violet = NoiseDitherer.VioletNoise; // Sharp, textured
var grey = NoiseDitherer.GreyNoise;     // Perceptually uniform

// Adjust strength and seed
var custom = NoiseDitherer.WhiteNoise.WithStrength(0.8f).WithSeed(12345);

Advanced Ditherers

High-quality ditherers for specialized applications with superior visual quality.

Ditherer Author Year Type Description
Yliluoma1 Joel Yliluoma 2011 Pattern Position-dependent mixing patterns; ref impl
Yliluoma2 Joel Yliluoma 2011 Pattern Improved Yliluoma with candidate counting; ref impl
Yliluoma3 Joel Yliluoma 2011 Pattern Threshold-based mixing; ref impl
Yliluoma4 Joel Yliluoma 2011 Pattern Balanced mixing strategy; ref impl
DbsDitherer Mitchel et al. 1987 Iterative Direct Binary Search optimization
Riemersma Thiadmer Riemersma 1998 Space-filling Hilbert/Peano curve error diffusion
Ostromoukhov Victor Ostromoukhov 2001 Adaptive Variable-coefficient error diffusion
Knoll Thomas Knoll 1990s Pattern Adobe Photoshop pattern dithering
NClosestDitherer - - Pattern N-closest palette color mixing
NConvexDitherer - - Pattern Convex combination of palette colors
VoidAndClusterDitherer Robert Ulichney 1993 Ordered Blue noise via void-and-cluster method
BarycentricDitherer - - Ordered Triangle-based 3-color interpolation with Bayer pattern
TinDitherer - - Ordered Tetrahedral 4-color interpolation with Bayer pattern
NaturalNeighbourDitherer - - Ordered Voronoi-based area-weighted color interpolation
AverageDitherer - - Custom Uses local region averages as thresholds
DizzyDitherer - - ErrorDiffusion Spiral-based error distribution reducing directional artifacts

Adaptive Ditherers

Ditherers that analyze local image content to adjust their behavior.

Ditherer Description
SmartDitherer Automatically selects best ditherer based on local content
AdaptiveDitherer Adjusts error diffusion strength based on local contrast
AdaptiveMatrixDitherer Uses content-aware threshold matrices
GradientAwareDitherer Preserves gradients while dithering flat areas
StructureAwareDitherer Maintains structural features
DebandingDitherer Specifically designed to reduce banding artifacts

Ditherer Configuration

Error diffusion ditherers support two scan modes via separate zero-cost types:

  • ErrorDiffusion - Linear left-to-right scanning
  • ErrorDiffusionSerpentine - Alternating direction per row (reduces directional artifacts)
// Basic usage (linear scan)
var ditherer = ErrorDiffusion.FloydSteinberg;

// Serpentine scanning (returns ErrorDiffusionSerpentine type - zero-cost abstraction)
var serpentine = ErrorDiffusion.FloydSteinberg.Serpentine;

// Switch back to linear if needed
var linear = serpentine.Linear;

// Adjust strength (0.0 - 1.0)
var reduced = ErrorDiffusion.Atkinson.WithStrength(0.75f);

// Combine options (serpentine with reduced strength)
var custom = ErrorDiffusion.JarvisJudiceNinke.Serpentine.WithStrength(0.9f);

Riemersma Ditherer (Space-Filling Curves)

The Riemersma ditherer uses space-filling curves to traverse the image, maintaining spatial locality for better error diffusion. Interactive visualization

Curve Type Subdivision Order Range Coverage per Order
Hilbert 2×2 1-7 2ⁿ × 2ⁿ pixels
Peano 3×3 1-5 3ⁿ × 3ⁿ pixels
Linear - - Serpentine scan
// Pre-configured instances
var hilbert = RiemersmaDitherer.Default;   // Hilbert curve, history size 16
var peano = RiemersmaDitherer.Peano;       // Peano curve, history size 16
var linear = RiemersmaDitherer.LinearScan; // Simple serpentine

// Different history sizes (affects error decay)
var small = RiemersmaDitherer.Small;  // History size 8 (faster)
var large = RiemersmaDitherer.Large;  // History size 32 (higher quality)

// Custom configuration with explicit curve type
var customHilbert = new RiemersmaDitherer(16, SpaceFillingCurve.Hilbert);
var customPeano = new RiemersmaDitherer(16, SpaceFillingCurve.Peano);

// Specify exact curve order (auto-calculated if omitted)
var hilbertOrder4 = new RiemersmaDitherer(16, SpaceFillingCurve.Hilbert, 4);  // 16×16 coverage
var peanoOrder3 = new RiemersmaDitherer(16, SpaceFillingCurve.Peano, 3);      // 27×27 coverage

Image Scaling / Pixel Art Rescaling

The library provides a comprehensive collection of image scaling algorithms, from simple interpolation methods to sophisticated pixel art scalers and retro gaming effects.

Upscaling Methods

using var source = new Bitmap("sprite.png");

// Pixel art scalers
using var scaled2x = source.Upscale(Eagle.X2);
using var scaled3x = source.Upscale(SuperEagle.X2);
using var hq4x = source.Upscale(Hqnx.X4);

// Anti-aliased scaling
using var smaa = source.Upscale(Smaa.X2);

// Edge-preserving smoothing
using var bilateral = source.Upscale(Bilateral.X2);

Available Scalers

Anti-Aliasing
Scaler Author Year Scales Description
Smaa Jorge Jimenez et al. 2012 2x, 3x, 4x Subpixel Morphological Anti-Aliasing - detects edges using luma gradients and applies weighted pixel blending. Presets: X2, X3, X4 with .Low, .Medium, .High, .Ultra quality variants.
Fxaa Timothy Lottes/NVIDIA 2009 2x, 3x, 4x Fast Approximate Anti-Aliasing using luma-based edge detection. Ref
Mlaa Alexander Reshetov 2009 2x, 3x, 4x Morphological Anti-Aliasing using pattern detection (L, Z, U shapes). Ref
ReverseAa Christoph Feck / Hyllian 2011 2x Reverse anti-aliasing using gradient-based tilt computation for smooth edges
Edge-Preserving Filters
Scaler Author Year Scales Description
Bilateral Tomasi & Manduchi 1998 2x, 3x, 4x Edge-preserving smoothing filter combining spatial and range weighting. Presets: X2, X3, X4 with .Soft (σs=2.0, σr=0.3) and .Sharp (σs=1.0, σr=0.1) variants.
Edge-Directed Interpolation
Scaler Author Year Scales Description
Nedi Xin Li & M.T. Orchard 2001 2x, 3x, 4x New Edge-Directed Interpolation using local autocorrelation for adaptive edge-aware upscaling. Ref
Nnedi3 tritical 2010 2x, 3x, 4x Neural Network Edge Directed Interpolation using trained weights for high-quality edge-directed scaling
SuperXbr Hyllian 2015 2x Super-Scale2x Refinement with 2-pass edge-directed scaling and anti-ringing
Pixel Art Scalers
Scaler Author Year Scales Description
Eagle - 1990s 2x, 3x Classic pixel doubling with corner detection
SuperEagle Kreed 2001 2x Enhanced Eagle with better diagonal handling
Super2xSaI Kreed 1999 2x 2x Scale and Interpolation engine
Epx / Scale2x Andrea Mazzoleni 2001 2x, 3x Edge-preserving pixel expansion
Hqnx Maxim Stepin 2003 2x, 3x, 4x High-quality magnification using YUV comparisons
Lqnx - - 2x, 3x, 4x Low-quality simplified variant of HQnx. Ref
Xbr Hyllian 2011 2x, 3x, 4x xBR (scale By Rules) edge-detection scaler
Xbrz Zenju 2012 2x-6x Enhanced xBR with improved edge handling
Sal Kreed 2001 2x Simple Assembly Language scaler with anti-aliasing
Mmpx Morgan McGuire 2021 2x Modern AI-inspired pixel art scaling
Omniscale libretro 2015 2x-6x Multi-method hybrid scaler
RotSprite Xenowhirl 2007 2x-4x Rotation-aware pixel art scaling
Clean - - 2x, 3x Clean edge pixel art scaler
TriplePoint Hawkynt 2011 2x, 3x 3x scaler using diagonal color analysis
ScaleNxSfx Sp00kyFox 2013 2x, 3x ScaleNx with effects (corner blending)
ScaleNxPlus Hawkynt 2011 2x, 3x Enhanced ScaleNx with better diagonals
ScaleHq Hawkynt 2011 2x, 3x HQ-style pixel art scaler
EpxB SNES9x Team 2003 2x Enhanced EPX with complex edge detection
EpxC - - 2x EPX variant with additional edge cases. Ref
Des FNES Team 2000 1x Diagonal Edge Scaling filter (pre-processing)
Des2 FNES Team 2000 2x DES with 2x scaling using edge-directed scaling
ScaleFx Sp00kyFox 2014 3x Scale3x with enhanced edge detection
Simple & Utility Scalers
Scaler Author Scales Description
NearestNeighbor - Nx Simple pixel duplication
Bilinear - Nx Linear interpolation
Bicubic - Nx Cubic spline interpolation
Lanczos - Nx Sinc-windowed interpolation
Normal - 2x, 3x, 4x Fixed-factor pixel duplication
Pixellate - Nx Pixelation/mosaic effect
BilinearPlus VBA Team 2x VBA weighted bilinear interpolation (5:2:1 weighting)
SharpBilinear LibRetro 2x, 3x, 4x Integer prescaling + bilinear for crisp pixels
Quilez Inigo Quilez 2x, 3x, 4x Quintic smoothstep interpolation for smooth gradients. Ref
NearestNeighborPlus - 2x, 3x, 4x Enhanced nearest neighbor with edge detection
Soft - 2x, 3x, 4x Soft interpolation with gentle blending
SoftSmart - 2x, 3x, 4x Smart soft interpolation with adaptive blending
Cut - 2x, 3x, 4x Cut-based scaling utility
Ddt Sp00kyFox 2x Diagonal De-interpolation Technique
CatmullRom - 2x, 3x, 4x Catmull-Rom spline interpolation (pixel-art variant)
Retro Display Effects
Scaler Author Scales Description
DotMatrix ScummVM 2x, 3x, 4x Dot-matrix display simulation with brightness falloff
LcdGrid - 2x, 3x, 4x LCD subpixel grid simulation
ScanlineHorizontal Hawkynt 2x1 CRT vertical scanline effect
ScanlineVertical Hawkynt 1x2 CRT horizontal scanline effect
Tv2x / Tv3x / Tv4x - 2x, 3x, 4x TV scanline simulation
MameRgb MAME Team 2x, 3x LCD RGB subpixel channel filter simulation
MameAdvInterp MAME Team 2x, 3x MAME advanced interpolation with scanline effect
HawkyntTv Hawkynt 2x, 3x, 4x TV effect with configurable scanline and phosphor patterns

Scaler Configuration

Many scalers support configuration options:

// SMAA quality levels
using var low = source.Upscale(Smaa.X2.Low);
using var ultra = source.Upscale(Smaa.X2.Ultra);

// Bilateral filter parameters
using var soft = source.Upscale(Bilateral.X2.Soft);    // σs=2.0, σr=0.3
using var sharp = source.Upscale(Bilateral.X2.Sharp);  // σs=1.0, σr=0.1
using var custom = source.Upscale(new Bilateral(3, 1.5f, 0.2f));

// Scanline brightness
using var scanlines = source.Upscale(new ScanlineHorizontal(brightness: 0.3f));

Image Resamplers

High-quality interpolation filters for arbitrary scaling to any resolution. Unlike pixel art scalers that work at fixed integer factors, resamplers use mathematical kernels to compute pixel values at any scale.

Resampling Methods

using Hawkynt.ColorProcessing.Resizing.Resamplers;

// Generic type syntax (parameterless)
using var result = bitmap.Resample<Lanczos3>(newWidth, newHeight);
using var result = bitmap.Resample<MitchellNetravali>(newWidth, newHeight);

// Instance syntax (parameterized)
using var result = bitmap.Resample(new Bicubic(-0.75f), newWidth, newHeight);
using var result = bitmap.Resample(new Gaussian(sigma: 1.0f), newWidth, newHeight);

Basic Filters

Resampler Radius Description
NearestNeighbor 1 Point sampling, fastest. Ref
Bilinear 1 2×2 weighted average. Ref
Box 1+ Simple averaging. Ref
Hermite 1 Smooth cubic polynomial. Ref
Cosine 1 Cosine-weighted interpolation. Ref
Smoothstep 1 Hermite polynomial S-curve interpolation. Ref

Cubic Family

Resampler Author Year Radius Parameters Reference
Bicubic Robert Keys 1981 2 a (-0.5f) Keys coefficient. Ref
MitchellNetravali Mitchell, Netravali 1988 2 b (1/3), c (1/3) Balanced cubic. Ref
CatmullRom Catmull, Rom 1974 2 None Sharp spline (B=0, C=0.5). Ref
Robidoux Nicolas Robidoux 2011 2 None Optimized for photos. Ref
RobidouxSharp Nicolas Robidoux 2011 2 None Sharper variant. Ref
RobidouxSoft Nicolas Robidoux 2011 2 None Smoother variant. Ref

Lanczos Family

Resampler Radius Sharpness Ringing Best For
Lanczos2 2 Good Low General use. Ref
Lanczos3 3 Very good Moderate Photos (recommended). Ref
Lanczos4 4 Excellent Higher Maximum sharpness. Ref
Lanczos5 5 Maximum Significant Special cases. Ref
Jinc 3+ Excellent Moderate 2D (uses Bessel J₁). Ref

B-Spline & O-MOMS

Resampler Degree Radius Prefilter Description
BSpline 3 2 Required Cubic B-spline. Ref
BSpline2 2 2 Required Quadratic. Ref
BSpline4 4 3 Required Quartic (Parzen). Ref
BSpline5 5 3 Required Quintic. Ref
BSpline7 7 4 Required Septic. Ref
OMoms3 3 2 Required Optimal cubic. Ref
OMoms5 5 3 Required Optimal quintic. Ref
OMoms7 7 4 Required Optimal septic. Ref

Spline & Window Filters

Resampler Radius Used By Description
Spline16 2 VLC 4-tap spline. Ref
Spline36 3 FFmpeg 6-tap spline. Ref
Spline64 4 ImageMagick 8-tap spline. Ref
Blackman 3+ - Very low sidelobes. Ref
Kaiser 3+ - Adjustable via beta parameter. Ref
Hann 3+ - Raised cosine. Ref
Hamming 3+ - Modified Hann. Ref
Welch 3+ - Parabolic window. Ref
Bartlett 3+ - Triangular window. Ref
Bohman 3+ - Cosine-convolved window. Ref
Nuttal 3+ - 4-term Blackman-Harris variant. Ref
BlackmanNuttal 3+ - Blackman-Nuttal hybrid. Ref
BlackmanHarris 3+ - 4-term Blackman-Harris. Ref
FlatTop 3+ - Very flat passband. Ref
Tukey 3+ - Tapered cosine window. Ref
Poisson 3+ - Exponential decay window. Ref
BartlettHann 3+ - Bartlett-Hann hybrid. Ref
Cauchy 3+ - Cauchy/Lorentz distribution window. Ref
Schaum2 2 - Quadratic Schaum interpolation. Ref
Schaum3 3 - Cubic Schaum interpolation. Ref

Lagrange Polynomial Interpolation

Resampler Degree Radius Description
Lagrange3 3 2 Cubic (4-point). Ref
Lagrange5 5 3 Quintic (6-point). Ref
Lagrange7 7 4 Septic (8-point). Ref

Note: Lagrange interpolation passes exactly through all sample points, making it suitable for applications requiring exact value preservation. No prefiltering is required.

Edge-Directed & Modern Upscalers

Resampler Author Year Radius Parameters Description
Dcci Li, Orchard 2001 2 cubicA, coherenceThreshold Edge-directed interpolation. Ref
Fsr AMD 2021 2 sharpness (0.5f) FidelityFX Super Resolution. Ref
Ravu - 2017 2 sharpness, antiRinging Robust Adaptive Video Upscaling. Ref
Eedi2 tritical 2005 2 - Enhanced Edge-Directed Interp. Ref
KrigBilateral - - 3 sigma, radius Kriging-based bilateral upscaling. Ref

Specialized Filters

Resampler Author Radius Parameters Description
Gaussian Gauss 2+ sigma (0.5f), radius Gaussian blur/interpolation. Ref
NoHalo Nicolas Robidoux 3 None Minimizes halo artifacts. Ref
LoHalo Nicolas Robidoux 3 None Low-halo variant. Ref
MagicKernelSharp John Googol 2 sharpness 4-tap max sharpness kernel. Ref

Resampler Parameters

Resampler Parameter Type Default Range Description
Bicubic a float -0.5f -1 to 0 Keys coefficient (-0.5=standard, -0.75=sharper)
MitchellNetravali b float 0.333f 0-1 Blur parameter
c float 0.333f 0-1 Ringing parameter
Kaiser radius int 3 1-10 Filter radius
beta float 8.6f 0-20 Shape parameter
Gaussian sigma float 0.5f 0.1-5 Standard deviation
Fsr sharpness float 0.5f 0-1 Sharpness level
Ravu sharpness float 0.5f 0-1 Sharpness level
antiRinging float 0.5f 0-1 Anti-ringing strength
Dcci cubicA float -0.5f -1 to 0 Cubic coefficient
coherenceThreshold float 0.3f 0-1 Edge detection threshold

Resampler Usage Examples

// High-quality photo scaling
using var photo = bitmap.Resample<Lanczos3>(newWidth, newHeight);

// Balanced quality (recommended for most uses)
using var balanced = bitmap.Resample<MitchellNetravali>(newWidth, newHeight);

// Sharp results with custom bicubic
using var sharp = bitmap.Resample(new Bicubic(-0.75f), newWidth, newHeight);

// Edge-preserving upscaling
using var edges = bitmap.Resample(Dcci.Sharp, newWidth, newHeight);

// Modern AI-like upscaling
using var fsr = bitmap.Resample(Fsr.Sharp, newWidth, newHeight);

// Halo-free scaling
using var nohalo = bitmap.Resample<NoHalo>(newWidth, newHeight);

// Smooth Gaussian
using var smooth = bitmap.Resample(new Gaussian(1.0f), newWidth, newHeight);

Algorithm Coverage

This library provides comprehensive coverage of resampling algorithms from major image processing libraries:

Source Library Algorithms Covered Notes
ImageMagick Point, Box, Triangle, Hermite, Cubic, Catrom, Mitchell, Lanczos, Spline, Gaussian, Kaiser, Blackman, Hann, Hamming, Jinc, Robidoux variants, Parzen (BSpline4), Lagrange, and all window functions Full coverage
FFmpeg libswscale Point, Bilinear, Bicubic, Lanczos, Spline16, Spline36, Gaussian, Sinc, Area Full coverage
GEGL NoHalo, LoHalo Full coverage
bisqwit.iki.fi Yliluoma 1-4, Knoll pattern dithering Full coverage

Installation

dotnet add package FrameworkExtensions.System.Drawing

License

LGPL 3.0 or later - See LICENSE for details

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net6.0-windows7.0 is compatible.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net7.0-windows7.0 is compatible.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net8.0-windows7.0 is compatible.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net9.0-windows7.0 is compatible.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.1 is compatible. 
.NET Framework net35 is compatible.  net40 is compatible.  net403 was computed.  net45 is compatible.  net451 was computed.  net452 was computed.  net46 was computed.  net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0.134 103 3/2/2026
1.0.0.132 113 2/16/2026
1.0.0.119 104 2/9/2026
1.0.0.112 107 2/2/2026
1.0.0.108 112 1/26/2026
1.0.0.91 110 1/19/2026
1.0.0.79 121 1/5/2026
1.0.0.70 130 12/29/2025
1.0.0.55 211 12/22/2025
1.0.0.49 232 12/15/2025
1.0.0.46 224 9/29/2025
1.0.0.45 216 8/4/2025
1.0.0.37 208 7/7/2025
1.0.0.36 254 2/24/2025
1.0.0.35 329 6/24/2024
1.0.0.33 210 6/17/2024
1.0.0.31 221 6/10/2024
1.0.0.30 204 5/27/2024
1.0.0.29 217 5/6/2024
1.0.0.27 215 4/29/2024
Loading failed