/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public override void Serialize(Stream stream, ColorCollection palette) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (palette == null) { throw new ArgumentNullException(nameof(palette)); } // TODO: Not writing 96 colors, but the entire contents of the palette, wether that's less than 96 or more using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) { writer.WriteLine(@"; Paint.NET Palette File ; Lines that start with a semicolon are comments ; Colors are written as 8-digit hexadecimal numbers: aarrggbb ; For example, this would specify green: FF00FF00 ; The alpha ('aa') value specifies how transparent a color is. FF is fully opaque, 00 is fully transparent. ; A palette must consist of ninety six (96) colors. If there are less than this, the remaining color ; slots will be set to white (FFFFFFFF). If there are more, then the remaining colors will be ignored."); foreach (Color color in palette) { writer.WriteLine("{0:X2}{1:X2}{2:X2}{3:X2}", color.A, color.R, color.G, color.B); } } }
/// <summary> /// Deserializes the <see cref="ColorCollection" /> contained by the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> that contains the palette to deserialize.</param> /// <returns>The <see cref="ColorCollection" /> being deserialized.</returns> public override ColorCollection Deserialize(Stream stream) { ColorCollection results; if (stream == null) { throw new ArgumentNullException(nameof(stream)); } results = new ColorCollection(); for (int i = 0; i < stream.Length / 3; i++) { int r; int g; int b; r = stream.ReadByte(); g = stream.ReadByte(); b = stream.ReadByte(); results.Add(Color.FromArgb(r, g, b)); } return(results); }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public override void Serialize(Stream stream, ColorCollection palette) { if (stream == null) { throw new ArgumentNullException("stream"); } if (palette == null) { throw new ArgumentNullException("palette"); } using (StreamWriter writer = new StreamWriter(stream, Encoding.UTF8)) { writer.WriteLine("JASC-PAL"); writer.WriteLine("0100"); writer.WriteLine(palette.Count); foreach (Color color in palette) { writer.Write("{0} ", color.R); writer.Write("{0} ", color.G); writer.Write("{0} ", color.B); writer.WriteLine(); } } }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream"/>. /// </summary> /// <param name="fileName">The name of the file where the palette will be written to.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public void Serialize(string fileName, ColorCollection palette) { using (Stream stream = File.Create(fileName)) { this.Serialize(stream, palette); } }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(ColorCollection other) { bool result; result = other != null && other.Count == this.Count; if (result) { // check colors - by value though, as Color.Cornflowerblue != Color.FromArgb(255, 100, 149, 237) for (int i = 0; i < this.Count; i++) { Color expected; Color actual; expected = other[i]; actual = this[i]; if (expected.ToArgb() != actual.ToArgb()) { result = false; break; } } } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="ColorCollection"/> class that contains elements copied from the specified collection. /// </summary> /// <param name="collection">The collection whose elements are copied to the new collection.</param> public ColorCollection(ColorCollection collection) : this() { for (int i = 0; i < collection.Count; i++) { this.Add(collection[i]); #if USENAMEHACK this.SetName(i, collection.GetName(i)); #endif } }
/// <summary> /// Deserializes the <see cref="ColorCollection" /> contained by the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> that contains the palette to deserialize.</param> /// <returns>The <see cref="ColorCollection" /> being deserialized.</returns> public override ColorCollection Deserialize(Stream stream) { ColorCollection results; if (stream == null) { throw new ArgumentNullException(nameof(stream)); } results = new ColorCollection(); using (StreamReader reader = new StreamReader(stream)) { string header; string version; int colorCount; // check signature header = reader.ReadLine(); version = reader.ReadLine(); if (header != "JASC-PAL" || version != "0100") { throw new InvalidDataException("Invalid palette file"); } colorCount = Convert.ToInt32(reader.ReadLine()); for (int i = 0; i < colorCount; i++) { int r; int g; int b; string data; string[] parts; data = reader.ReadLine(); parts = !string.IsNullOrEmpty(data) ? data.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries) : new string[0]; if (!int.TryParse(parts[0], out r) || !int.TryParse(parts[1], out g) || !int.TryParse(parts[2], out b)) { throw new InvalidDataException(string.Format("Invalid palette contents found with data '{0}'", data)); } results.Add(Color.FromArgb(r, g, b)); } } return(results); }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public override void Serialize(Stream stream, ColorCollection palette) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (palette == null) { throw new ArgumentNullException(nameof(palette)); } throw new NotSupportedException(); }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public override void Serialize(Stream stream, ColorCollection palette) { int swatchIndex; if (stream == null) { throw new ArgumentNullException("stream"); } if (palette == null) { throw new ArgumentNullException("palette"); } swatchIndex = 0; // TODO: Allow name and columns attributes to be specified using (StreamWriter writer = new StreamWriter(stream, Encoding.ASCII)) { writer.WriteLine("GIMP Palette"); writer.WriteLine("Name: "); writer.WriteLine("Columns: 8"); writer.WriteLine("#"); foreach (Color color in palette) { writer.Write("{0,-3} ", color.R); writer.Write("{0,-3} ", color.G); writer.Write("{0,-3} ", color.B); #if USENAMEHACK writer.Write(palette.GetName(swatchIndex)); #else if (color.IsNamedColor) { writer.Write(color.Name); } else { writer.Write("#{0:X2}{1:X2}{2:X2} Swatch {3}", color.R, color.G, color.B, swatchIndex); } #endif writer.WriteLine(); swatchIndex++; } } }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public override void Serialize(Stream stream, ColorCollection palette) { int count; if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (palette == null) { throw new ArgumentNullException(nameof(palette)); } count = palette.Count; if (count > 256) { throw new InvalidDataException("A maximum of 255 colors are supported by this format."); } foreach (Color color in palette) { stream.WriteByte(color.R); stream.WriteByte(color.G); stream.WriteByte(color.B); } if (count < 256) { // add padding for (int i = count; i < 256; i++) { stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte(0); } // add an extra four bytes which seem to describe the number // of used colours stream.WriteByte(0); stream.WriteByte((byte)count); stream.WriteByte(0); stream.WriteByte(0); } stream.Flush(); }
/// <summary> /// Deserializes the <see cref="ColorCollection" /> contained by the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> that contains the palette to deserialize.</param> /// <returns>The <see cref="ColorCollection" /> being deserialized.</returns> public override ColorCollection Deserialize(Stream stream) { ColorCollection results; int count; if (stream == null) { throw new ArgumentNullException(nameof(stream)); } results = new ColorCollection(); count = (int)(stream.Length / 3); for (int i = 0; i < count; i++) { int r; int g; int b; r = stream.ReadByte(); g = stream.ReadByte(); b = stream.ReadByte(); results.Add(Color.FromArgb(r, g, b)); } if (count == 257) { int realCount; // undocumented on the spec page, but when poking around // the Optimized Colors preset files of CS2, I found that // four extra bytes were added to some files. The second of // these extra bytes specified how many colours are // really in use (anything else is just padding) realCount = results[256].G; while (results.Count > realCount) { results.RemoveAt(realCount); } } return(results); }
protected virtual void CreateScale() { ColorCollection custom; Color color; RgbaChannel channel; custom = new ColorCollection(); color = this.Color; channel = this.Channel; for (int i = 0; i < 254; i++) { int a; int r; int g; int b; a = color.A; r = color.R; g = color.G; b = color.B; switch (channel) { case RgbaChannel.Red: r = i; break; case RgbaChannel.Green: g = i; break; case RgbaChannel.Blue: b = i; break; case RgbaChannel.Alpha: a = i; break; } custom.Add(Color.FromArgb(a, r, g, b)); } this.CustomColors = custom; }
public void Serialize(Stream stream, ColorCollection palette, AdobePhotoshopColorSwatchFileVersion version, AdobePhotoshopColorSwatchColorSpace colorSpace) { if (stream == null) { throw new ArgumentNullException("stream"); } if (palette == null) { throw new ArgumentNullException("palette"); } if (version == AdobePhotoshopColorSwatchFileVersion.Version2) { this.WritePalette(stream, palette, AdobePhotoshopColorSwatchFileVersion.Version1, colorSpace); } this.WritePalette(stream, palette, version, colorSpace); }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public override void Serialize(Stream stream, ColorCollection palette) { if (stream == null) { throw new ArgumentNullException(nameof(stream)); } if (palette == null) { throw new ArgumentNullException(nameof(palette)); } foreach (Color color in palette) { stream.WriteByte(color.R); stream.WriteByte(color.G); stream.WriteByte(color.B); } stream.Flush(); }
public static ColorCollection GetPalette(ColorPalette palette) { ColorCollection result; switch (palette) { case ColorPalette.Named: result = NamedColors; break; case ColorPalette.Office2010: result = Office2010Standard; break; case ColorPalette.Paint: result = PaintPalette; break; case ColorPalette.Standard: result = QbColors; break; case ColorPalette.None: result = new ColorCollection(); break; case ColorPalette.WebSafe: result = WebSafe; break; case ColorPalette.Standard256: result = StandardPalette; break; default: throw new ArgumentException("Invalid palette", "palette"); } return(result); }
/// <summary> /// Deserializes the <see cref="ColorCollection" /> contained by the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> that contains the palette to deserialize.</param> /// <returns>The <see cref="ColorCollection" /> being deserialized.</returns> public override ColorCollection Deserialize(Stream stream) { ColorCollection results; if (stream == null) { throw new ArgumentNullException(nameof(stream)); } results = new ColorCollection(); using (StreamReader reader = new StreamReader(stream)) { while (!reader.EndOfStream) { string line; line = reader.ReadLine(); if (!string.IsNullOrEmpty(line) && !line.StartsWith(";") && line.Length == 8) { int a; int r; int g; int b; a = int.Parse(line.Substring(0, 2), NumberStyles.HexNumber); r = int.Parse(line.Substring(2, 2), NumberStyles.HexNumber); g = int.Parse(line.Substring(4, 2), NumberStyles.HexNumber); b = int.Parse(line.Substring(6, 2), NumberStyles.HexNumber); results.Add(Color.FromArgb(a, r, g, b)); } } } return(results); }
public static ColorCollection ScaledPalette(IEnumerable <Color> topRow) { ColorCollection results; results = new ColorCollection(); topRow = topRow.ToArray(); results.AddRange(topRow); for (int i = 5; i >= 0; i--) { foreach (Color color in topRow) { HslColor hsl; hsl = new HslColor(color); hsl.L = (5 + i + (16 * i)) / 100D; results.Add(hsl.ToRgbColor()); } } return(results); }
protected virtual void WritePalette(Stream stream, ColorCollection palette, AdobePhotoshopColorSwatchFileVersion version, AdobePhotoshopColorSwatchColorSpace colorSpace) { int swatchIndex; this.WriteInt16(stream, (short)version); this.WriteInt16(stream, (short)palette.Count); swatchIndex = 0; foreach (Color color in palette) { short value1; short value2; short value3; short value4; swatchIndex++; switch (colorSpace) { case AdobePhotoshopColorSwatchColorSpace.Rgb: value1 = (short)(color.R * 256); value2 = (short)(color.G * 256); value3 = (short)(color.B * 256); value4 = 0; break; case AdobePhotoshopColorSwatchColorSpace.Hsb: value1 = (short)(color.GetHue() * 182.04); value2 = (short)(color.GetSaturation() * 655.35); value3 = (short)(color.GetBrightness() * 655.35); value4 = 0; break; case AdobePhotoshopColorSwatchColorSpace.Grayscale: if (color.R == color.G && color.R == color.B) { // already grayscale value1 = (short)(color.R * 39.0625); } else { // color is not grayscale, convert value1 = (short)(((color.R + color.G + color.B) / 3.0) * 39.0625); } value2 = 0; value3 = 0; value4 = 0; break; default: throw new InvalidOperationException("Color space not supported."); } this.WriteInt16(stream, (short)colorSpace); this.WriteInt16(stream, value1); this.WriteInt16(stream, value2); this.WriteInt16(stream, value3); this.WriteInt16(stream, value4); if (version == AdobePhotoshopColorSwatchFileVersion.Version2) { string name; #if USENAMEHACK name = palette.GetName(swatchIndex - 1); if (string.IsNullOrEmpty(name)) { name = string.Format("Swatch {0}", swatchIndex); } #else name = color.IsNamedColor ? color.Name : string.Format("Swatch {0}", swatchIndex); #endif this.WriteInt32(stream, name.Length); this.WriteString(stream, name); } } }
protected virtual ColorCollection ReadPalette(Stream stream, AdobePhotoshopColorSwatchFileVersion version) { int colorCount; ColorCollection results; results = new ColorCollection(); // read the number of colors, which also occupies two bytes colorCount = this.ReadInt16(stream); for (int i = 0; i < colorCount; i++) { AdobePhotoshopColorSwatchColorSpace colorSpace; int value1; int value2; int value3; string name; // again, two bytes for the color space colorSpace = (AdobePhotoshopColorSwatchColorSpace)(this.ReadInt16(stream)); value1 = this.ReadInt16(stream); value2 = this.ReadInt16(stream); value3 = this.ReadInt16(stream); this.ReadInt16(stream); // only CMYK supports this field. As we can't handle CMYK colors, we read the value to advance the stream but don't do anything with it if (version == AdobePhotoshopColorSwatchFileVersion.Version2) { int length; // need to read the name even though currently our colour collection doesn't support names length = ReadInt32(stream); name = this.ReadString(stream, length); } else { name = string.Empty; } switch (colorSpace) { case AdobePhotoshopColorSwatchColorSpace.Rgb: int red; int green; int blue; // RGB. // The first three values in the color data are red , green , and blue . They are full unsigned // 16-bit values as in Apple's RGBColor data structure. Pure red = 65535, 0, 0. red = value1 / 256; green = value2 / 256; blue = value3 / 256; results.Add(Color.FromArgb(red, green, blue)); break; case AdobePhotoshopColorSwatchColorSpace.Hsb: double hue; double saturation; double brightness; // HSB. // The first three values in the color data are hue , saturation , and brightness . They are full // unsigned 16-bit values as in Apple's HSVColor data structure. Pure red = 0,65535, 65535. hue = value1 / 182.04; saturation = value2 / 655.35; brightness = value3 / 655.35; results.Add(new HslColor(hue, saturation, brightness).ToRgbColor()); break; case AdobePhotoshopColorSwatchColorSpace.Grayscale: int gray; // Grayscale. // The first value in the color data is the gray value, from 0...10000. gray = (int)(value1 / 39.0625); results.Add(Color.FromArgb(gray, gray, gray)); break; default: throw new InvalidDataException(string.Format("Color space '{0}' not supported.", colorSpace)); } #if USENAMEHACK results.SetName(i, name); #endif } return(results); }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified Stream. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> void IPaletteSerializer.Serialize(Stream stream, ColorCollection palette) { this.Serialize(stream, palette); }
public void Serialize(Stream stream, ColorCollection palette, AdobePhotoshopColorSwatchColorSpace colorSpace) { this.Serialize(stream, palette, AdobePhotoshopColorSwatchFileVersion.Version2, colorSpace); }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream"/>. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public abstract void Serialize(Stream stream, ColorCollection palette);
/// <summary> /// Deserializes the <see cref="ColorCollection" /> contained by the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> that contains the palette to deserialize.</param> /// <returns>The <see cref="ColorCollection" /> being deserialized.</returns> public override ColorCollection Deserialize(Stream stream) { byte[] buffer; string header; ColorCollection results; if (stream == null) { throw new ArgumentNullException(nameof(stream)); } results = new ColorCollection(); // read the FORM header that identifies the document as an IFF file buffer = new byte[4]; stream.Read(buffer, 0, buffer.Length); if (Encoding.ASCII.GetString(buffer) != "FORM") { throw new InvalidDataException("Form header not found."); } // the next value is the size of all the data in the FORM chunk // We don't actually need this value, but we have to read it // regardless to advance the stream this.ReadInt32(stream); // read either the PBM or ILBM header that identifies this document as an image file stream.Read(buffer, 0, buffer.Length); header = Encoding.ASCII.GetString(buffer); if (header != "PBM " && header != "ILBM") { throw new InvalidDataException("Bitmap header not found."); } while (stream.Read(buffer, 0, buffer.Length) == buffer.Length) { int chunkLength; chunkLength = this.ReadInt32(stream); if (Encoding.ASCII.GetString(buffer) != "CMAP") { // some other LBM chunk, skip it if (stream.CanSeek) { stream.Seek(chunkLength, SeekOrigin.Current); } else { for (int i = 0; i < chunkLength; i++) { stream.ReadByte(); } } } else { // color map chunk! for (int i = 0; i < chunkLength / 3; i++) { int r; int g; int b; r = stream.ReadByte(); g = stream.ReadByte(); b = stream.ReadByte(); results.Add(Color.FromArgb(r, g, b)); } // all done so stop reading the rest of the file break; } // chunks always contain an even number of bytes even if the recorded length is odd // if the length is odd, then there's a padding byte in the file - just read and discard if (chunkLength % 2 != 0) { stream.ReadByte(); } } return(results); }
public void Serialize(Stream stream, ColorCollection palette, AdobePhotoshopColorSwatchFileVersion version) { this.Serialize(stream, palette, version, AdobePhotoshopColorSwatchColorSpace.Rgb); }
/// <summary> /// Serializes the specified <see cref="ColorCollection" /> and writes the palette to a file using the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> used to write the palette.</param> /// <param name="palette">The <see cref="ColorCollection" /> to serialize.</param> public override void Serialize(Stream stream, ColorCollection palette) { this.Serialize(stream, palette, AdobePhotoshopColorSwatchColorSpace.Rgb); }
/// <summary> /// Deserializes the <see cref="ColorCollection" /> contained by the specified <see cref="Stream" />. /// </summary> /// <param name="stream">The <see cref="Stream" /> that contains the palette to deserialize.</param> /// <returns>The <see cref="ColorCollection" /> being deserialized.</returns> public override ColorCollection Deserialize(Stream stream) { ColorCollection results; if (stream == null) { throw new ArgumentNullException("stream"); } results = new ColorCollection(); using (StreamReader reader = new StreamReader(stream)) { string header; int swatchIndex; bool readingPalette; readingPalette = false; // check signature header = reader.ReadLine(); if (header != "GIMP Palette") { throw new InvalidDataException("Invalid palette file"); } // read the swatches swatchIndex = 0; while (!reader.EndOfStream) { string data; data = reader.ReadLine(); if (!string.IsNullOrEmpty(data)) { if (data[0] == '#') { // comment readingPalette = true; } else if (!readingPalette) { // custom attribute } else if (readingPalette) { int r; int g; int b; string[] parts; string name; // TODO: Optimize this a touch. Microoptimization? Maybe. parts = !string.IsNullOrEmpty(data) ? data.Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries) : new string[0]; name = parts.Length > 3 ? string.Join(" ", parts, 3, parts.Length - 3) : null; if (!int.TryParse(parts[0], out r) || !int.TryParse(parts[1], out g) || !int.TryParse(parts[2], out b)) { throw new InvalidDataException(string.Format("Invalid palette contents found with data '{0}'", data)); } results.Add(Color.FromArgb(r, g, b)); #if USENAMEHACK results.SetName(swatchIndex, name); #endif swatchIndex++; } } } } return(results); }