To Pixel Art Tools
Version 1.0 Unity 6000.x+ Clouded Studio

To Pixel Art Tools

Turn any image into pixel art, entirely inside Unity. No external tools, no Python, no third party packages, no internet connection — the whole conversion is native C#.

Section 1Overview

To Pixel Art Tools converts photographs, renders, illustrations and existing sprites into pixel art through a configurable pipeline of eight stages. It is built around a live preview, because the right colour count or merge tolerance for a given image is something you find by watching the image, not by reasoning about numbers.

Requirements

ItemRequirement
Unity6000.x (Unity 6) or newer
Render pipelineAny — Built-in, URP and HDRP. The tool does not render anything.
PlatformsAll. The runtime API works in every build target, including WebGL.
DependenciesNone. No packages, no native plugins, no network access.

What is in the package

FolderContents
Runtime/The conversion pipeline, settings, profile and palette assets. Assembly CloudedStudio.ToPixelArtTools.
Editor/The window, inspectors, batch tools and exporters. Assembly CloudedStudio.ToPixelArtTools.Editor, editor only.
Documentation/This document and a plain text manual.

The package can be moved or renamed anywhere inside Assets. It locates its own files at runtime, so reorganising your project will not break it.

Build size

If you never call the API from your own code, the runtime assembly costs a few kilobytes and nothing else — Unity strips assemblies that nothing references. The editor assembly is never included in a build.

Section 2Getting started

Your first conversion

  1. Open Window ▸ Clouded Studio ▸ To Pixel Art Tools ▸ Convert to Pixel Art.
  2. Drag an image into the window, assign a project texture in Source, or choose Open External Image… for a PNG/JPG/JPEG that should remain outside the project.
  3. Pick a starting point from the Presets menu in the toolbar — see section 6 for which one suits your source.
  4. Adjust the settings on the left. The preview reconverts as you go.
  5. Press Convert and Save.

The result is written into Assets with a _PixelArt suffix, already imported with point filtering, no compression and no mipmaps — the settings pixel art needs in order to stay crisp in game. Project sources can save beside themselves; external originals are never imported.

Where everything lives

MenuWhat it does
Window ▸ Clouded Studio ▸ To Pixel Art Tools ▸ Convert to Pixel Art Opens the main conversion window.
Window ▸ … ▸ Batch Convert… Converts a whole project selection with a saved profile.
Window ▸ … ▸ Create Preset Profiles Writes one profile asset per built in preset.
Window ▸ … ▸ Documentation Opens the text manual.
Assets ▸ Clouded Studio ▸ To Pixel Art Tools ▸ Convert to Pixel Art… Right-click an image in the Project window to open it in the tool.
Assets ▸ … ▸ Batch Convert… Right-click a selection or a folder to batch convert it.
Assets ▸ … ▸ Create Palette from Image Extracts a palette asset from the selected image.
Assets ▸ Create ▸ Clouded Studio ▸ To Pixel Art Tools Creates an empty Pixel Art Profile or Color Palette asset.

Section 3The conversion window

Settings on the left, live preview on the right.

Preview controls

ActionHow
ZoomMouse wheel over the preview, or the − and + buttons. Zooming follows the cursor, so the detail you are pointing at stays under the pointer.
PanMiddle mouse drag, or Alt + left drag.
Fit to windowFit
Actual size1:1
Compare before and afterSet the view mode to Compare, then drag the white divider.
Pixel gridGrid, drawn once you pass 8× magnification.
Scale referenceScale Reference ▸ Choose Image…, then drag the overlay around.

Compare draws both images into the same rectangle rather than side by side, so the divider reveals the same region of each. That is what makes it possible to judge whether a shape survived the conversion, instead of only whether the two images look similar.

Scale reference

The overlay exists for one question that comes up constantly: is this the right resolution for my game? Drop in a character sprite you already ship and compare directly, rather than guessing from a pixel count.

Live preview

The preview reconverts a fraction of a second after you stop changing something. Conversion runs on a background thread and is cancelled the moment another change arrives, so dragging a slider stays responsive even on large images.

Turn Live Preview off in the toolbar when working with a long animation and use Refresh to convert on demand. Above 24 frames the window tells you so.

The information bar

128 × 128 px  ·  factor 4×  ·  palette 32  ·  41 colours in output  ·  86 ms

Palette is how many colours the quantizer produced. Colours in output is what the final image actually contains. They differ when a stage placed after Pixel Art blends new colours in — Outline and Diffuse both do. If you need the palette to be exact, move those stages above Pixel Art or turn them off.

Section 4How the pipeline works

A conversion is a list of stages run top to bottom. You can drag them into any order in the Pipeline list, and the order changes the result more than most of the individual settings do.

Pixel Art is the pivot. Everything above it works on the full resolution source; everything below it works on the finished low resolution grid, where every pixel is one of only a few thousand and each one is clearly visible.

FULL RESOLUTION SOURCE — e.g. 512 × 512 REDUCED PIXEL GRID — e.g. 128 × 128 Smooth remove noise Background Removal key colour to alpha Color Removal colour list to alpha Pixel Art downscale + quantize + optional dither resolution drops here Despeckle repaint colour specks Outline edge the silhouette Diffuse painterly blend Island Removal delete detached fragments
Stages above the Pixel Art stage operate on the full resolution image; stages below it operate on the reduced grid. This is the default order; dragging a stage across that line changes what it does, not just when it runs. For example, the Painted preset deliberately moves Diffuse above Pixel Art.

What moving a stage actually changes

StageAbove Pixel ArtBelow Pixel Art
Smooth Stops noise from being baked into pixels. This is where it belongs. Just blurs the finished result.
Background Removal Edge peeling has full resolution material to work with. Almost always correct. Each peeled layer costs a whole output pixel.
Color Removal Matches colours sampled from the source before quantization changes them. The usual placement. Useful when you specifically want to remove colours from the final palette.
Despeckle Nothing meaningful to do — stray pixels do not exist yet. Removes the specks quantization left. This is where it belongs.
Outline Drawn at full resolution then reduced: softer, thinner, partly anti-aliased. Drawn onto the grid: exactly the thickness you asked for.
Diffuse A painting effect applied to the source. Scatters your finished pixels. Occasionally the effect you want, usually not.
Island Removal Measures components in source pixels, so the configured size rarely means what you intend. Measures detached fragments on the final grid. This is where it belongs.

Section 5Stage reference

Each stage has an Enabled checkbox, shown both in the Pipeline list and inside its own section. Pixel Art is the exception: it is the conversion itself, so it always runs.

5.1Smooth

Noise reduction that preserves edges, applied to the colour channels only. Alpha is never touched — softening it would reintroduce exactly the semi transparent fringe the rest of the pipeline works to remove.

SettingRangeWhat it does
MethodBilateral · Total VariationWhich algorithm to run.
Sigma Color0.02 – 0.5Bilateral. How different two colours may be and still be averaged together. Higher smooths across stronger colour changes.
Sigma Spatial0.5 – 10Bilateral. Radius of influence in pixels. Cost grows with the square of this value.
Weight0.02 – 0.5Total Variation. Higher produces broader, flatter blocks of colour.

Bilateral is a blur whose weights are additionally scaled by how similar each neighbour's colour is. A neighbour across a strong edge contributes almost nothing, so noise inside a flat region is averaged away while the edge stays exactly where it was. That property is the point: an edge blurred before the resolution drop becomes a visibly wrong pixel afterwards.

Total Variation minimises the total amount of change across the image while staying close to the original. The result is piecewise constant — regions collapse into flat plateaus separated by sharp steps, which is a very good match for what pixel art wants.

Cost

Smooth runs at full source resolution by default and is by far the most expensive stage. If the preview feels sluggish, this is almost always why. Lower Sigma Spatial first.

5.2Background Removal

Turns a flat background colour into transparency, in two passes.

SettingRangeWhat it does
Key ColoranyThe background colour to remove. White by default.
Tolerance0 – 255First pass, applied everywhere. Keep it low.
Edge Tolerance0 – 255Second pass, applied only to pixels touching background already removed.
Edge Passes0 – 15How many layers of blended edge to peel away. 0 disables the second pass.

The split is the whole design. A single threshold cannot tell a background apart from a light area inside your subject, so set low it leaves a halo and set high it punches holes. The second pass can be far more permissive precisely because an enclosed area never touches the outside and is therefore unreachable by it.

Distance is measured as the largest single channel difference from the key colour, which is stricter than an average — a pixel matching on two channels but clearly off on the third is correctly kept.

Tuning order

Start at tolerance 25, edge tolerance 80, 3 passes. If a halo remains, raise Edge Passes before you touch either tolerance. If part of your subject vanished, lower Tolerance — that is the pass that reaches everywhere.

5.3Color Removal

Turns pixels matching any selected colour into full transparency. Use Add Color as many times as needed; each swatch participates in the same pass, and the corresponding Remove button deletes only that entry.

SettingRangeWhat it does
Colorszero or moreThe list of RGB colours to remove. The stage makes no change while the list is empty.
Tolerance0 – 255Maximum allowed difference on every RGB channel. 0 removes exact matches only.

Matching uses the largest difference on any RGB channel. With tolerance 10, a pixel is removed only when its red, green and blue channels are each no more than 10 away from at least one selected colour. The selected swatch's alpha is ignored, and a match clears all four channels to zero.

Placement

Keep Color Removal above Pixel Art when the swatches came from the original image, before quantization changes those colours. Move it below Pixel Art only when you intend to remove colours produced by the final palette.

5.4Pixel Art

The conversion itself: resolution reduction, then colour quantization, then optional clean up.

Downscale

MethodUse when
NearestArt with clean shapes. Samples the centre of each block, so edges stay perfectly hard.
BoxHeavy anti aliasing or fine detail, where Nearest would sample noise at random.
LAB AverageSame as Box, but mixes colour perceptually. Blue and yellow average to green rather than to mud.

Both averaging methods weight the average by alpha, so fully transparent pixels cannot drag the visible colour of a block toward whatever arbitrary value they happen to store.

Factor is how many source pixels become one output pixel; a factor of 4 turns 512 into 128. Automatic Factor measures how wide the image's existing runs of identical colour already are — that recovers the real block size of art that was drawn small and scaled up. If the source has no block structure at all, it falls back to whatever factor lands the longest side near 256 pixels. It is a starting point, not an answer.

Quantization

MethodNotes
K-MeansClusters the image's colours perceptually. Best quality and the default. Deterministic from a seed.
Median CutThe classic fast algorithm. Splits along RGB axes, so it can spend entries on wide but visually unimportant gradients.
Fixed PaletteMaps onto a palette asset you supply. Guarantees consistency across every asset using it.
SettingRangeWhat it does
Colors2 – 256Requested palette size. Hidden when a fixed palette is assigned.
Palette Seed0 – 9999K-Means. A different seed gives a different but equally valid palette.
Ignore Transparent Pixelson / offLeaves fully transparent pixels out of palette building.
Palette Seed

If two or three colours land somewhere you dislike, nudging the seed is usually faster than fighting the colour count. Clustering has many good answers; the seed picks which one you get, and the same seed always gives the same result.

Ignore Transparent Pixels is on by default and should usually stay on. The colour stored underneath a transparent pixel is arbitrary and never visible, so including it just consumes palette entries you will never see.

Dithering

Dithering spreads the quantization error so a small palette can suggest colours it does not actually contain. Without it, a gradient mapped onto twelve colours becomes twelve hard bands. With it, the boundary between two palette colours becomes a mix of both and reads as smooth from a normal viewing distance.

No dither — banding
Error diffusion
Ordered 4×4
6 colours

Interactive illustration of the principle: one gradient reduced to the same few colours three ways. Drag the slider down to see how far dithering can stretch a very small palette.

MethodCharacter
Floyd–SteinbergError diffusion. Organic, irregular texture that follows the image. The closest match to the original, and the best choice for a still image.
Ordered 2×2Very coarse, strongly visible pattern.
Ordered 4×4The classic retro cross hatch. A good default when the dithering should read as a deliberate style.
Ordered 8×8The finest, smoothest ordered pattern.

Dither Strength (0 – 1) scales how much error is spread. Below 1 keeps the pattern subtle while still breaking up the worst banding, which usually suits artwork better than full strength does.

Both methods measure error perceptually. The ordered methods nudge each pixel along the direction of its own quantization error rather than along a fixed axis — so they dither correctly across boundaries between colours that differ in hue, not only across boundaries in brightness. Floyd–Steinberg scans in a serpentine pattern, alternating direction every row, which cancels the diagonal streaking that a single scan direction leaves in flat areas.

Dithering and clean up cancel out

Dithering works by placing isolated, alternating pixels — which is exactly what Merge Runs and the Despeckle stage exist to remove. Use one or the other. The window warns you when both are on.

For animations, prefer an ordered method

Ordered patterns depend only on pixel position, so they are identical from frame to frame. Error diffusion depends on the whole image, so a small change between frames reshuffles the noise and the pattern visibly crawls during playback.

Merge Runs

Sweeps rows and then columns, collapsing sequences of near identical colours into one flat colour. This is the automated version of the clean up an artist does by hand — a region that already reads as one flat colour still contains a dozen barely different values, and actually making it one colour is what makes the result look deliberate. Sweeping rows and columns also reinforces horizontal and vertical structure, which is the bias hand made pixel art has.

SettingRangeWhat it does
Merge Tolerance0 – 50Maximum perceptual distance for two pixels to join the same run.
Merge Passes1 – 8How many horizontal plus vertical sweeps to run.

Tolerance is measured perceptually, so the numbers correspond to something real: about 2 is the threshold of human vision, 8–12 merges what already looks the same, and 15–25 deliberately flattens shading into bands.

Color Transfer

Applies the tone, saturation and contrast of any reference image to the result. The two images need nothing in common — a sunset photograph will push a sprite toward warm tones and lift its contrast the way the sunset's own does. Statistics are gathered from visible pixels only, so a large transparent margin cannot dictate the result.

Because the transfer moves every pixel independently and produces a continuous gradient, the image is re-quantized afterwards to bring it back to a pixel art palette.

Alpha Threshold and Sharpen

Alpha Threshold (0 – 255) forces alpha to be either fully transparent or fully opaque. Anti aliasing leaves a rim of partially transparent pixels that is invisible at full resolution but becomes a row of washed out pixels on a grid — and a visible seam wherever the sprite is drawn over a different background. Set it to 0 to keep the original alpha.

Sharpen applies a light sharpening kernel to the colour channels, useful after Box or LAB Average downscaling. Alpha is deliberately excluded so it cannot undo the alpha threshold that just ran.

5.5Despeckle

Removes connected regions smaller than Minimum Region Size (1 – 30), repainting them with the colour that occurs most often immediately around them. Regions of transparency count too. Passes (1 – 8) repeats the sweep; it stops early once nothing changes.

This catches what Merge Runs structurally cannot. A single misplaced pixel forms no run in either direction, so a row and column sweep always leaves it behind — and it is exactly the kind of speck that makes an image read as noisy rather than drawn.

5.6Outline

Darkens the boundary between distinct colour regions and around the silhouette, which is what gives hand drawn pixel art its readable shape.

SettingRangeWhat it does
Thickness1 – 4Outline width in pixels, grown inward.
Strength0 – 1How far to blend toward the outline colour. 1 replaces the pixel outright.
ColoranyThe outline colour.
Minimum Contrast0 – 255How different two neighbouring colours must be to count as an edge.

Minimum Contrast is the setting that decides whether this looks good. Too low and the outline traces every small step the quantizer left behind, turning the sprite into a wireframe. Around 90 is a good starting point for sprites; at 255 only the silhouette is drawn.

The outline is drawn on the inside of the silhouette, so it never grows the sprite's footprint. The image border is never treated as an edge — a full bleed background will not come back with a frame drawn around it.

5.7Diffuse

ModeWhat it does
AnisotropicBlends the four quadrants around each pixel, weighted by how uniform each one is. Edges survive because a quadrant straddling an edge always has high variance and contributes little; flat areas are cleanly averaged. An oil painting effect.
RandomReplaces each pixel with a random neighbour.
DarkenSame, but only when the neighbour is darker.
LightenSame, but only when the neighbour is lighter.
SettingRangeWhat it does
Radius1 – 6Quadrant size in Anisotropic; how far a pixel may travel in the scattering modes.
Sharpness0 – 10Anisotropic. How strongly the most uniform quadrant dominates.
Iterations1 – 10Scattering modes. How many times to repeat.
Fixed Seed / Seed0 – 9999Scattering modes. Turn Fixed Seed off for a different scatter every run.

Anisotropic blends the quadrants rather than picking a single winner as a classic Kuwahara filter does. Near an edge the four variances end up similar, so no quadrant dominates and the result is a slight mix right at the boundary — that soft transition is what reads as a brush stroke instead of hard posterisation. Low Sharpness around 0.2–0.4 blends generously; 8 and above converges on the hard classic look.

5.8Island Removal

Deletes small foreground components that are disconnected from the rest of the image by transparency. Unlike Despeckle, it does not look for a small patch of one colour or repaint it from its neighbours: it considers all connected non-transparent pixels part of the same island and makes qualifying islands fully transparent.

SettingRangeWhat it does
Maximum Island Size1 – 4096Removes components containing this many pixels or fewer. A value of 3 removes islands of 1, 2 or 3 pixels and preserves islands of 4 or more.
Transparency Threshold1 – 255Alpha values below this threshold count as transparent while connected components are found.

Connectivity includes all eight neighbours, so pixels touching diagonally belong to the same island. Transparency Threshold only controls this classification; it does not otherwise change partially transparent pixels that belong to a preserved component. Use Pixel Art's Alpha Threshold as well when the output itself should have hard alpha edges.

Placement

Keep Island Removal below Pixel Art so sizes are measured on the final pixel grid and it can remove fragments introduced by downscaling or quantization.

Section 6Presets

The settings interact, and the useful combinations are not obvious from the individual controls. A photograph needs smoothing before the resolution drop or the quantizer spends its palette on noise; clean vector style art needs none and is only softened by it. The presets encode those pairings.

Pick one from the Presets menu in the toolbar. Nothing is written to disk — use Window ▸ … ▸ Create Preset Profiles if you want them as assets.

PresetBuilt forKey choices
Clean Sprite Character and object art that already has clear shapes. Nearest · K-Means 32 · merge runs · despeckle · alpha threshold
Bold Outline Sprite Sprites that must read over busy backgrounds. Clean Sprite plus a 1 px outline at contrast 90
Photo to Pixel Art Photographs and highly detailed renders. Bilateral smoothing · Box downscale · K-Means 32 · despeckle
Environment and Backgrounds Large scenes rather than single objects. LAB Average · K-Means 64 · gentle merge tolerance
Retro 16 Colors A deliberate hardware era look. K-Means 16 · heavy merging and despeckling
Dithered Retro Gradients on a very limited palette. K-Means 12 · Ordered 4×4 dither at 0.8 · merging and despeckling off
Painted A painted rather than sampled feel. Diffuse moved above Pixel Art · Box downscale · K-Means 48

Section 7Animations

If your file name ends in a number — walk_001.png, walk01.png, walk-1.png, frame1.png — the other frames beside it are detected automatically and an Animation Sequence checkbox appears.

With it on, every frame is converted together against one shared palette. This is not a convenience. Quantizing frames independently lets each shade drift by a step or two between frames, which is invisible in a still comparison and impossible to miss once the animation plays.

Use the timeline under the preview to scrub or play back at a chosen frame rate. Convert and Save writes every frame, each keeping its original file name.

Frames that are not numbered consistently

Detection needs the same prefix, the same extension and a trailing number. If your frames do not match, select them all in the Project window and use Batch Convert with Share One Palette instead — it reaches the same result without renaming anything.

Section 8Batch conversion

Select any number of images or folders in the Project window, then Assets ▸ Clouded Studio ▸ To Pixel Art Tools ▸ Batch Convert…. Pick a profile, decide whether to share one palette, and convert.

You can also add external PNG, JPG and JPEG files or folders, or drag several into the batch window. Project and external sources can be mixed. External results always go to the configured folder inside Assets, even when Save Next to Source is enabled, so originals remain outside the project.

The progress bar is cancellable, and anything that fails is reported at the end rather than stopping the run at the first error.

Share One Palette builds a single palette from every selected image and applies it to all of them. Worth considering for tilesets, icon sets and anything else that is seen together: converted image by image, they end up with colours that almost match, which reads as sloppy in a way that is hard to name but easy to see.

The More menu in the conversion window batches the current selection using the settings you are looking at, which is convenient once you have dialled them in.

Section 9Profiles

A profile is an asset holding a complete set of conversion settings plus the palette and reference image they use. Finding the settings that suit a project's art style takes real experimentation, and once found they should be applied identically to everything from then on.

TaskHow
Create from current settingsSave As… in the window toolbar.
Create emptyAssets ▸ Create ▸ Clouded Studio ▸ To Pixel Art Tools ▸ Pixel Art Profile
Update an existing oneSave.
Discard changesRevert.
Edit with a live previewOpen in To Pixel Art Window, at the top of the profile inspector.
Share across projectsImport and export JSON, from the window's More menu or the profile inspector.

Profiles are plain assets, so they diff and merge in version control like anything else. Editing one in its inspector supports undo normally.

Forward compatible

A profile saved by an older version that is missing a stage added later still loads — the stage list is rebuilt and the new stage takes its default position, rather than the file being rejected.

Section 10Palettes

Locking a set of assets to one palette is the difference between a collection of sprites and a coherent art style. Create one with Assets ▸ Create ▸ Clouded Studio ▸ To Pixel Art Tools ▸ Color Palette.

ToolWhat it does
Import…Reads .hex, .txt and GIMP .gpl files. Blank lines and comments are ignored, so a file mixing notes with colours still loads.
Export…Writes the palette out as a plain hexadecimal list.
Extract FromDerives a palette from an image by clustering its colours — the usual way an artist gets a palette is by pointing at art they like.
Sort by HueGroups by colour family, near greys first. Makes a large palette far easier to read.
Sort by LuminanceOrders from darkest to lightest.

To use a palette, set Quantization to Fixed Palette and assign it. Right clicking an image in the Project window also offers Create Palette from Image directly.

Section 11Output and import settings

By default the result is written next to the source with a _PixelArt suffix. Overwrite Existing is off: re-running a conversion while dialling in settings is normal, and silently replacing a result that prefabs and scenes may already reference is not a sensible default. Writing over the source image is blocked outright.

Apply Import Settings configures the written texture the way pixel art needs:

Import settingValueWhy
Filter ModePointAnything else blurs the pixels you just created.
CompressionUncompressedBlock compression mottles flat colour areas.
Mip MapsOff2D art is drawn at a fixed scale.
Non-Power-of-2NoneRescaling on import would destroy the pixel grid.
Max SizeLarge enough for the resultStops the importer shrinking the image.
Alpha Is TransparencyOnCorrect filtering around transparent edges.
Wrap ModeClampNo bleeding from the opposite edge.

Turn on Import as Sprite to set the texture type and pixels per unit at the same time.

The tool reads the original file, not the imported texture

Import settings such as maximum size and compression therefore do not affect the conversion, and your source does not need Read/Write enabled. The artwork on disk is the source of truth. Textures with no file behind them — generated at runtime, for instance — are read from the texture itself.

Section 12Scripting API

Everything the window does is available from code, in the editor and in builds. Namespace: CloudedStudio.ToPixelArtTools.

Converting textures

Texture2D PixelArtConverter.Convert(Texture2D source, PixelArtProfile profile)

Converts a texture with a saved profile. Returns a new point filtered texture that you own — destroy it when you are done.

Texture2D PixelArtConverter.Convert(Texture2D source, PixelArtPipelineSettings settings, PixelArtPipelineResources resources = null, CancellationToken cancellationToken = default)

Converts with settings built in code.

Texture2D[] PixelArtConverter.ConvertSequence(IReadOnlyList<Texture2D> frames, …)

Converts several textures against one shared palette, as animation frames must be.

Task<Texture2D> PixelArtConverter.ConvertAsync(Texture2D source, PixelArtPipelineSettings settings, PixelArtPipelineResources resources = null, IProgress<PixelArtProgress> progress = null, CancellationToken cancellationToken = default)

Runs the processing off the main thread. The texture is read before the task starts and the result texture created after it finishes, both on the calling thread, so no Unity object is ever touched from a worker.

// With a profile asset.
Texture2D result = PixelArtConverter.Convert(source, profile);

// With settings built in code.
var settings = new PixelArtPipelineSettings();
settings.PixelArt.ColorCount = 24;
settings.PixelArt.AutomaticFactor = false;
settings.PixelArt.Factor = 4;
settings.PixelArt.Dither = DitherMethod.Ordered4x4;
settings.ColorRemoval.Enabled = true;
settings.ColorRemoval.Colors.Add(new Rgba32(255, 0, 255));
settings.ColorRemoval.Colors.Add(new Rgba32(0, 255, 0));
settings.ColorRemoval.Tolerance = 8;
settings.Despeckle.Enabled = true;
settings.IslandRemoval.Enabled = true;
settings.IslandRemoval.MaximumIslandSize = 3;
settings.IslandRemoval.TransparencyThreshold = 1;

Texture2D custom = PixelArtConverter.Convert(source, settings);

// Starting from a preset, then adjusting.
var photo = PixelArtPresets.CreateByName("Photo to Pixel Art");
photo.PixelArt.ColorCount = 48;

// Animation frames sharing one palette.
Texture2D[] frames = PixelArtConverter.ConvertSequence(sourceFrames, settings);

Working with buffers directly

PixelBuffer is a plain RGBA32 byte buffer with no engine dependency — which is what makes the pipeline safe to run on a background thread, and what lets it be unit tested outside Unity.

PixelBuffer buffer = TextureConverter.ToPixelBuffer(sourceTexture);
PixelArtConversionResult result = PixelArtPipeline.ProcessDetailed(buffer, settings);

Debug.Log($"factor {result.DownscaleFactor}, palette {result.Palette.Count}");

Texture2D texture = TextureConverter.ToTexture2D(result.Frame);
byte[] png = TextureConverter.EncodeToPng(result.Frame);
MemberMeaning
PixelArtConversionResult.FramesConverted images, in the order supplied.
PixelArtConversionResult.FrameThe first frame. Convenient for single image conversions.
PixelArtConversionResult.DownscaleFactorThe factor used, whether configured or detected.
PixelArtConversionResult.PaletteThe palette every frame was mapped onto.
PixelBuffer.CountDistinctColors()How many distinct colours the result actually contains.

Palettes and resources

var palette = new ColorPalette(new[]
{
    new Rgba32(0, 0, 0),
    new Rgba32(255, 255, 255),
});

var resources = new PixelArtPipelineResources { FixedPalette = palette };
settings.PixelArt.Quantization = QuantizationMethod.FixedPalette;

Texture2D result = PixelArtConverter.Convert(source, settings, resources);
ResourceUsed when
FixedPaletteQuantization is set to Fixed Palette. Ignored otherwise.
PrecomputedPaletteAlways. Overrides palette generation entirely — this is how batch conversion shares one palette across many images.
ColorTransferReferenceColour transfer is enabled.

Settings object

MemberTypeNotes
OrderList<PipelineStep>Execution order. Every stage appears exactly once.
SmoothSmoothSettingsEnabled, Method, SigmaColor, SigmaSpatial, TvWeight
BackgroundRemovalBackgroundRemovalSettingsEnabled, KeyColor, Tolerance, EdgeTolerance, EdgePasses
ColorRemovalColorRemovalSettingsEnabled, Colors, Tolerance
PixelArtPixelArtSettingsDownscale, AutomaticFactor, Factor, Quantization, ColorCount, IgnoreTransparentPixels, PaletteSeed, Dither, DitherStrength, MergeRuns, MergeTolerance, MergePasses, ColorTransferEnabled, ColorTransferStrength, AlphaThreshold, Sharpen
DespeckleDespeckleSettingsEnabled, MinimumRegionSize, Passes
OutlineOutlineSettingsEnabled, Thickness, Strength, Color, MinimumContrast
DiffuseDiffuseSettingsEnabled, Mode, Radius, Sharpness, Iterations, UseFixedSeed, Seed
IslandRemovalIslandRemovalSettingsEnabled, MaximumIslandSize, TransparencyThreshold

Clone() returns a deep copy safe to hand to another thread. Normalize() repairs a settings object loaded from disk: it fills in null sections and rebuilds an incomplete stage order. Call it after deserialising settings yourself.

Determinism

Guaranteed

Given the same input and settings, the pipeline produces byte identical output on every platform and regardless of how many threads it used. Nothing depends on UnityEngine.Random, System.Random or wall clock time. The single exception is Diffuse with Fixed Seed turned off, which is opt in.

This matters more than it might seem: it means a conversion can run in CI, results can be committed, and a regression in your art pipeline shows up as a real diff rather than as noise.

Section 13Performance

Indicative figures for a 512 × 512 source on a modern desktop CPU, reducing by 4×:

ConfigurationTime
Pixel Art only, K-Means 32 colours~40 ms
Plus bilateral smoothing (Sigma Spatial 2)~120 ms
Plus total variation smoothing~600 ms

Section 14Troubleshooting

The result has more colours than my colour count

A stage after Pixel Art is blending new colours in — Outline and Diffuse both do. Move them above Pixel Art in the pipeline list, or turn them off. The information bar shows both numbers so you can see it happening.

The output looks noisy and speckled

The source has detail in every pixel and Nearest is sampling it at random. Switch Downscale to Box or LAB Average, enable Smooth, and turn on Despeckle.

I turned on dithering but the pattern is gone

Merge Runs or Despeckle removed it. Both exist to delete isolated pixels, and the dither pattern is made of isolated pixels. Turn them off.

The dither pattern crawls when my animation plays

Switch from Floyd–Steinberg to one of the ordered methods. Error diffusion depends on the whole image, so any small change between frames reshuffles the noise; ordered patterns depend only on position and stay locked in place.

I see banding in a gradient

The palette has run out of colours. Raise Colors, or turn on Dither to trade the bands for texture — often the better trade at low colour counts.

Background removal ate part of my subject

Lower Tolerance — that is the pass which reaches everywhere. Raise Edge Passes instead to clean the remaining halo, since the edge pass cannot reach enclosed areas.

Background removal left a halo

Raise Edge Passes first, then Edge Tolerance. Leave Tolerance low.

I need to remove several unrelated colours

Use Color Removal instead of Background Removal, add every colour to its list, and raise Tolerance gradually. Keep it above Pixel Art when the swatches came from the source image. At tolerance 0 only exact RGB matches are removed.

Small disconnected pixels remain after removing the background

Enable Island Removal, keep it below Pixel Art, and set Maximum Island Size to the largest fragment that should disappear. Raise Transparency Threshold if a semi-transparent fringe is still joining the fragment to the subject.

The outline is everywhere and the sprite looks like a wireframe

Raise Minimum Contrast. It is tracing quantization steps rather than real transitions.

Colours shimmer between animation frames

Turn on Animation Sequence so all frames share one palette. If your frames are not numbered consistently, select them all and use Batch Convert with Share One Palette.

The preview does not match my imported asset

Expected. The tool reads the original file rather than the imported texture, so import settings such as maximum size and compression do not affect the conversion. See section 11.

The window is slow with a long animation

Turn off Live Preview in the toolbar and use Refresh to convert on demand. Above 24 frames the window says so.

“Fixed palette quantization was selected but no palette was supplied.”

Assign a palette asset in the Pixel Art section, or switch the quantization method to K-Means or Median Cut.

Section 15Support

Questions, bug reports and feature requests are welcome. To get a useful answer quickly, please include:

To Pixel Art Tools · Version 1.0 · Clouded Studio