Skip to content

PictureProfile

Namespace Nfty.Core.Imaging in assembly Nfty.Core.

public sealed class PictureProfile

A picture's embedded ICC profile, read by nfty's own reader, and the one conversion of it to sRGB both front-ends use.

Remarks

Why convert. nfty stores and publishes pixels with no profile, and everything downstream (marketplaces, browsers, game engines) reads untagged pixels as sRGB. A picture drawn in Display P3 or Adobe RGB, imported byte for byte, therefore looks duller and shifted everywhere it travels. Converting at import makes the stored pixels mean what the artist saw.

Never parsed by ImageSharp: the raw profile is lifted out of the file's own container by IccProfileBytes and read by IccRgbProfile (profile at most 1 MB, 100 tags, 4096 curve entries).

The conversion, per pixel: each channel through its tone curve to linear (a 256-entry table per channel), the profile's colorant matrix to PCS XYZ (D50), Bradford D50 to D65, the IEC 61966-2-1 XYZ-to-linear-sRGB matrix, clamp to 0..1, then the sRGB transfer function back to 8 bits by searching a table of the 255 midpoints between codes (round to nearest, ties to the upper code). All in Double, no SIMD, nothing culture-dependent, so the same picture converts to the same bytes on every machine. Alpha is untouched. Out-of-gamut colors clip per channel: the simple, predictable answer, and what a "relative colorimetric" convert does.

Order on a value-map layer: converted FIRST, then ImageImport.ToValueMap() takes its lightness, so a Dynamic/Static layer's grays are the lightness of the colors the artist saw.

Properties

CanConvert

public bool CanConvert { get; }

Whether PictureProfile.ConvertToSrgb() can run.

ConvertedLine

public string ConvertedLine { get; }

The line the CLI prints when it converted.

Kind

public PictureProfileKind Kind { get; }

What the profile means for the picture.

Name

public string Name { get; }

The profile's name as the note prints it (its own desc, or a description when it gives none).

NoProfile

public static PictureProfile NoProfile { get; }

A picture with no profile.

Note

public string? Note { get; }

The sentence the import form shows, or null when there is nothing to say (no profile, or sRGB).

Methods

ConvertToSrgb(Image<Rgba32>)

public void ConvertToSrgb(Image<Rgba32> image);

Converts a decoded picture's pixels from this profile to sRGB, in place. Alpha is untouched.

Parameters

  • image (Image<Rgba32>) - The picture, decoded from the file this profile was read from.

Exceptions

FromFile(ReadOnlySpan<byte>)

public static PictureProfile FromFile(ReadOnlySpan<byte> file);

Reads the profile embedded in encoded picture bytes. Never throws for any input.

Parameters

  • file (ReadOnlySpan<byte>) - The whole PNG or JPEG.

Returns. What it carries.

FromProfile(ReadOnlySpan<byte>)

public static PictureProfile FromProfile(ReadOnlySpan<byte> profile);

Reads a raw ICC profile. Never throws for any input.

Parameters

  • profile (ReadOnlySpan<byte>) - The profile bytes.

Returns. What it means for a picture carrying it.

Read(string)

public static PictureProfile Read(string path);

Reads the profile embedded in a picture file.

Parameters

  • path (string) - The PNG or JPEG.

Returns. What it carries.

Exceptions

  • IOException - The file cannot be read.