public static ValueSet GetValueSetForSinglePixel(this ILCCColorSpace cs, ColorF color, bool useChroma) { // a value set normally consists of multiple luma & chroma components for a char (for example 5 luma + 2 chroma) // for this we just have the normal default 3-component. all our colorspaces are LCC (luma chroma chroma). LCCColorDenorm denorm = cs.RGBToLCC(color); ValueSet src = new ValueSet(); float[] normArray = new float[] { (float)cs.NormalizeL(denorm.L), (float)cs.NormalizeC1(denorm.C1), (float)cs.NormalizeC2(denorm.C2), }; ValueSet.Init(ref src, useChroma ? 3 : 1, 0, normArray); src.DenormalizedValues[0] = (float)denorm.L; src.DenormalizedValues[1] = (float)denorm.C1; src.DenormalizedValues[2] = (float)denorm.C2; return(src); }
public static ILCCColorSpace ParseRequiredLCCColorSpaceArgs(string[] args, bool allowDefault = false) { ILCCColorSpace ret = null; args.ProcessArg("-cs", o => { switch (o.ToLowerInvariant()) { case "jpeg": ret = new JPEGColorspace(); break; case "nyuv": ret = new NaiveYUVColorspace(); break; case "lab": ret = new LABColorspace(); break; case "hsl": ret = new HSLColorspace(); break; default: throw new Exception(string.Format("Unknown LCC colorspace: {0}", o)); } }); if (ret == null) { if (allowDefault) { ret = new LABColorspace(); } else { throw new Exception("Colorspace not specified"); } } return(ret); }
static void CreateLUT(string paletteName, System.Drawing.Color[] palette, string outfile, ILCCColorSpace cs, int levels, bool useChroma, bool neutral) { Log.WriteLine("Creating LUT..."); Log.WriteLine(" Palette: {0} ({1} colors)", paletteName, palette.Length); Log.WriteLine(" Colorspace: {0}", cs.ToString()); Log.WriteLine(" Output file: {0}", outfile); Log.WriteLine(" {0}", useChroma ? "COLOR" : "GREY"); int imageWidth = levels * levels; int imageHeight = levels; Log.WriteLine(" Image size: {0} x {1}", imageWidth, imageHeight); Directory.CreateDirectory(Path.GetDirectoryName(outfile)); var bmp = new Bitmap(imageWidth, imageHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb); BitmapData destFontData = bmp.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); int chromaComponents = useChroma ? 2 : 0; for (double ir = 0; ir < levels; ++ir) { for (double ig = 0; ig < levels; ++ig) { for (double ib = 0; ib < levels; ++ib) { // Y coord = green (top = 0, bottom = 1) // X coord = red (left = 0; right = 1) // X cell = blue (left = 0; right = 1) ColorF srcColor = ColorF.FromRGB(ir / levels, ig / levels, ib / levels); //srcColor = ColorF.FromRGB(.5,.3,.2); int y = levels - (int)ig - 1; int x = (int)ib * levels; x += (int)ir; if (neutral) { destFontData.SetPixel(x, y, srcColor); } else { // find the nearest color in the palette. // a value set normally consists of multiple luma & chroma components for a char (for example 5 luma + 2 chroma) // for this we just have the normal default. all our colorspaces are LCC (luma chroma chroma). ValueSet srcValueSet = cs.GetValueSetForSinglePixel(srcColor, useChroma); System.Drawing.Color closestColor = System.Drawing.Color.Black; double closestDistance = 1e6; foreach (var pc in palette) { ColorF paletteColor = pc.ToColorF(); ValueSet palValueSet = cs.GetValueSetForSinglePixel(paletteColor, useChroma); double dist = cs.ColorDistance(srcValueSet, palValueSet, 1 /*luma L*/, chromaComponents); if (dist < closestDistance) { closestDistance = dist; closestColor = pc; } } //closestColor = srcColor; destFontData.SetPixel(x, y, closestColor); //destFontData.SetPixel(x, y, srcColor); } } } } bmp.UnlockBits(destFontData); bmp.Save(outfile); bmp.Dispose(); bmp = null; }