Skip to content

Instantly share code, notes, and snippets.

@ShunMc

ShunMc/AcoImporter.cs

Last active Mar 31, 2019
Embed
What would you like to do?
AcoImporter
using System.IO;
using UnityEngine;
using UnityEditor;
using UnityEditor.Experimental.AssetImporters;
using PhotoshopFile;
[ScriptedImporter(1, "aco")]
public class AcoImporter : ScriptedImporter
{
public override void OnImportAsset(AssetImportContext ctx)
{
var colors = AcoDecoder.ReadFile(ctx.assetPath);
var type = System.Type.GetType("UnityEditor.ColorPresetLibrary, UnityEditor");
var instance = ScriptableObject.CreateInstance(type);
var method = type.GetMethod("Add");
foreach (var color in colors)
{
method.Invoke(instance, new object[] { color.color, color.name });
}
AssetDatabase.CreateAsset(instance, "Assets/Editor/" + Path.GetFileNameWithoutExtension(ctx.assetPath) + ".colors");
AssetDatabase.SaveAssets();
}
public class AcoDecoder
{
private enum ColorSpace
{
Rgb = 0,
Hsb = 1,
Cmyk = 2,
Lab = 7, // not supported
Grayscale = 8,
WideCmyk = 9
}
private struct ColorSpec
{
public ColorSpace colorSpace;
public ushort w;
public ushort x;
public ushort y;
public ushort z;
public ColorSpec(ushort _colorSpace, ushort _w, ushort _x, ushort _y, ushort _z)
{
colorSpace = (ColorSpace)_colorSpace;
w = _w;
x = _x;
y = _y;
z = _z;
}
}
public static ColorPreset[] ReadFile(string fileName)
{
using (Stream stream = File.OpenRead(fileName))
{
var binary = new PsdBinaryReader(stream, System.Text.Encoding.UTF8);
int version = binary.ReadUInt16();
if (version != 1 && version != 2)
{
throw new InvalidDataException("This file has an unknown version.");
}
var colorPresets = ReadColorPresets(binary, version);
if (version == 1)
{
version = binary.ReadUInt16();
if (version == 2)
{
colorPresets = ReadColorPresets(binary, version, colorPresets);
}
}
return colorPresets;
}
}
private static ColorPreset[] ReadColorPresets(PsdBinaryReader binary, int version, ColorPreset[] presets = null)
{
ushort nc = binary.ReadUInt16();
var results = presets ?? new ColorPreset[nc];
for (int i = 0; i < nc; i++)
{
bool shouldReadColor = false;
if (results[i] == null)
{
results[i] = new ColorPreset();
shouldReadColor = true;
}
var colorPreset = results[i];
if (shouldReadColor)
{
var color = new ColorSpec(binary.ReadUInt16(), binary.ReadUInt16(), binary.ReadUInt16(), binary.ReadUInt16(), binary.ReadUInt16());
switch (color.colorSpace)
{
case ColorSpace.Rgb:
colorPreset.color = new Color(color.w / 65535f, color.x / 65535f, color.y / 65535f);
break;
case ColorSpace.Hsb:
colorPreset.color = Color.HSVToRGB(color.w / 65535f, color.x / 65535f, color.y / 65535f);
break;
case ColorSpace.Cmyk:
{
float c = 1 - color.w / 65535f;
float m = 1 - color.x / 65535f;
float y = 1 - color.y / 65535f;
float k = 1 - color.z / 65535f;
colorPreset.color = new Color((1 - c) * (1 - k), (1 - m) * (1 - k), (1 - y) * (1 - k));
}
break;
case ColorSpace.Lab:
// float l = color.w / 100; // 0 - 100
// float a = color.x / 100; // -128 - 127
// float b = color.y / 100; // -128 - 127
throw new InvalidDataException("ColorSpace.Lab is not supported.");
case ColorSpace.Grayscale:
float gray = color.w / 10000f;
colorPreset.color = new Color(gray, gray, gray);
break;
case ColorSpace.WideCmyk:
{
float c = color.w / 10000f;
float m = color.x / 10000f;
float y = color.y / 10000f;
float k = color.z / 10000f;
colorPreset.color = new Color((1 - c) * (1 - k), (1 - m) * (1 - k), (1 - y) * (1 - k));
}
break;
default:
throw new InvalidDataException(string.Format("Color space '{0}' is not supported.", color.colorSpace));
}
}
else
{
binary.BaseStream.Position += 10;
}
colorPreset.name = version == 2 ? binary.ReadUnicodeString() : null;
}
return results;
}
}
public class ColorPreset
{
public Color color;
public string name;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.