Download CorelDrawPalPaletteWriter.zip, last updated 05/08/2018 (30.38 KB)

Download
  • md5: 5dc2a39ffc96357d70d670fae102a69c
  • sha1: 87cd30771c13132db0584ebbc03986265fa278dc
  • sha256: 9cc4800ea9713c1d7f95660b1deba20f3c13e9f317171b2cbc0ff358ace10f7e
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;

// Working with CorelDRAW Palettes part 1, reading .pal files
// https://www.cyotek.com/blog/reading-coreldraw-palettes-part-1-pal-files
// Copyright © 2018 Cyotek Ltd. All Rights Reserved.

// Working with CorelDRAW Palettes part 2, writing .pal files
// https://www.cyotek.com/blog/working-with-coreldraw-palettes-part-2-writing-pal-files
// Copyright © 2018 Cyotek Ltd. All Rights Reserved.

// This work is licensed under the Creative Commons Attribution 4.0 International License.
// To view a copy of this license, visit http://creativecommons.org/licenses/by/4.0/.

// Found this example useful? 
// https://www.paypal.me/cyotek

namespace Cyotek.Demonstrations.CorelDrawPaletteWriter
{
  internal sealed class CorelDrawPalette : IEnumerable<Color>
  {
    #region Constants

    private readonly List<Color> _palette;

    #endregion

    #region Constructors

    public CorelDrawPalette()
    {
      _palette = new List<Color>();
    }

    public CorelDrawPalette(IEnumerable<Color> colors)
    {
      if (colors == null)
      {
        throw new ArgumentNullException(nameof(colors));
      }

      _palette = new List<Color>(colors);
    }

    #endregion

    #region Static Methods

    public static CorelDrawPalette LoadFrom(string fileName)
    {
      CorelDrawPalette palette;

      palette = new CorelDrawPalette();
      palette.Load(fileName);

      return palette;
    }

    public static CorelDrawPalette LoadFrom(Stream stream)
    {
      CorelDrawPalette palette;

      palette = new CorelDrawPalette();
      palette.Load(stream);

      return palette;
    }

    private static byte ClampCmyk(float value)
    {
      if (value < 0 || float.IsNaN(value))
      {
        value = 0;
      }

      return Convert.ToByte(value * 100);
    }

    #endregion

    #region Properties

    public int Count
    {
      get { return _palette.Count; }
    }

    public Color this[int index]
    {
      get { return _palette[index]; }
    }

    #endregion

    #region Methods

    public void Load(string fileName)
    {
      using (Stream stream = File.OpenRead(fileName))
      {
        this.Load(stream);
      }
    }

    public void Load(Stream stream)
    {
      _palette.Clear();

      using (TextReader reader = new StreamReader(stream, Encoding.ASCII, false, 1024, true))
      {
        string line;

        while ((line = reader.ReadLine()) != null && (line.Length == 0 || line[0] != (char)26))
        {
          if (!string.IsNullOrEmpty(line))
          {
            int lastQuote;
            int numberPosition;
            byte cyan;
            byte magenta;
            byte yellow;
            byte black;

            lastQuote = line.LastIndexOf('"');

            if (lastQuote == -1)
            {
              throw new InvalidDataException("Unable to parse line.");
            }

            numberPosition = lastQuote + 1;
            cyan = this.NextNumber(line, ref numberPosition);
            magenta = this.NextNumber(line, ref numberPosition);
            yellow = this.NextNumber(line, ref numberPosition);
            black = this.NextNumber(line, ref numberPosition);

            _palette.Add(this.ConvertCmykToRgb(cyan, magenta, yellow, black));
          }
        }
      }
    }

    public void Save(string fileName)
    {
      using (Stream stream = File.Create(fileName))
      {
        this.Save(stream);
      }
    }

    public void Save(Stream stream)
    {
      int longestSwatchName;
      StringBuilder sb;

      longestSwatchName = this.GetLongestName();

      sb = new StringBuilder(longestSwatchName + 20);

      using (TextWriter writer = new StreamWriter(stream, Encoding.ASCII, 1024, true))
      {
        for (int i = 0; i < _palette.Count; i++)
        {
          Color color;
          string name;

          color = _palette[i];
          name = color.Name;
          this.ConvertRgbToCmyk(color, out byte c, out byte m, out byte y, out byte k);

          this.WriteName(sb, name, longestSwatchName);
          this.WriteNumber(sb, c);
          this.WriteNumber(sb, m);
          this.WriteNumber(sb, y);
          this.WriteNumber(sb, k);

          writer.WriteLine(sb.ToString());
          sb.Length = 0;
        }
      }
    }

    public Color[] ToArray()
    {
      return _palette.ToArray();
    }

    private Color ConvertCmykToRgb(int c, int m, int y, int k)
    {
      int r;
      int g;
      int b;
      float multiplier;

      multiplier = 1 - k / 100F;

      r = Convert.ToInt32(255 * (1 - c / 100F) * multiplier);
      g = Convert.ToInt32(255 * (1 - m / 100F) * multiplier);
      b = Convert.ToInt32(255 * (1 - y / 100F) * multiplier);

      return Color.FromArgb(r, g, b);
    }

    private void ConvertRgbToCmyk(Color color, out byte c, out byte m, out byte y, out byte k)
    {
      float r;
      float g;
      float b;
      float divisor;

      r = color.R / 255F;
      g = color.G / 255F;
      b = color.B / 255F;

      divisor = 1 - Math.Max(Math.Max(r, g), b);

      c = ClampCmyk((1 - r - divisor) / (1 - divisor));
      m = ClampCmyk((1 - g - divisor) / (1 - divisor));
      y = ClampCmyk((1 - b - divisor) / (1 - divisor));
      k = ClampCmyk(divisor);
    }

    private int GetLongestName()
    {
      int result;

      result = 32;

      for (int i = 0; i < _palette.Count; i++)
      {
        string name;

        name = _palette[i].Name;

        if (!string.IsNullOrEmpty(name) && name.Length > result)
        {
          result = name.Length;
        }
      }

      return result;
    }

    private byte NextNumber(string line, ref int start)
    {
      int length;
      int valueLength;
      int maxLength;
      byte result;

      // skip any leading spaces
      while (char.IsWhiteSpace(line[start]))
      {
        start++;
      }

      length = line.Length;
      maxLength = Math.Min(3, length - start);
      valueLength = 0;

      for (int i = 0; i < maxLength; i++)
      {
        if (char.IsDigit(line[start + i]))
        {
          valueLength++;
        }
        else
        {
          break;
        }
      }

      result = byte.Parse(line.Substring(start, valueLength));

      start += valueLength;

      return result;
    }

    private void WriteName(StringBuilder sb, string name, int longestSwatchName)
    {
      sb.Append('"');
      sb.Append(name);
      sb.Append('"');

      //sb.Append(new string(' ', longestSwatchName - name.Length));

      for (int j = (name ?? string.Empty).Length; j < longestSwatchName; j++)
      {
        sb.Append(' ');
      }
    }

    private void WriteNumber(StringBuilder sb, byte value)
    {
      //sb.Append(value.ToString().PadRight(4));

      if (value == 100)
      {
        sb.Append("100 ");
      }
      else
      {
        sb.Append(' ');
        if (value < 10)
        {
          sb.Append(' ');
        }

        sb.Append(value);

        sb.Append(' ');
      }
    }

    #endregion

    #region IEnumerable<Color> Interface

    public IEnumerator<Color> GetEnumerator()
    {
      return ((IEnumerable<Color>)_palette).GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
      return this.GetEnumerator();
    }

    #endregion
  }
}

Donate

Donate