Some of my domain objects have Color and Image properties that need to be persisted, so I've created a ColorType and an ImageType class.
So far it seems to be working, but I don't fully understand what all the different virtual members are used for or what parameters will be passed.
I just wanted to make sure I haven't done something silly that could cause trouble down the track.
Code:
public class ColorType : ValueTypeType
{
    public ColorType()
        : base(new Int32SqlType()) {}
    private int? ColorToInt32(object Value)
    {
        if (!Color.Empty.Equals(Value))
            return ((Color)Value).ToArgb();
        else
            return null;
    }
    private Color Int32ToColor(object Value)
    {
        if (Value is int)
            return Color.FromArgb((int)Value);
        else
            return Color.Empty;
    }
    public override string ObjectToSQLString(object val)
    {
        return ((Int32Type)NHibernateUtil.Int32).ObjectToSQLString(ColorToInt32(val));
    }
    public override object FromStringValue(string xml)
    {
        return Int32ToColor(NHibernateUtil.Int32.FromStringValue(xml));
    }
    public override object Get(IDataReader rs, string name)
    {
        return Get(rs, rs.GetOrdinal(name));
    }
    public override object Get(IDataReader rs, int index)
    {
        return Int32ToColor(NHibernateUtil.Int32.Get(rs, index));
    }
    public override void Set(IDbCommand cmd, object value, int index)
    {
        NHibernateUtil.Int32.Set(cmd, ColorToInt32(value), index);
    }
    public override string Name
    {
        get { return "Color"; }
    }
    public override Type ReturnedClass
    {
        get { return typeof(Color); }
    }
}
Code:
public class ImageType : MutableType
{
    internal sealed class Png : ImageType
    {
        public Png()
            : base(ImageFormat.Png) { }
    }
    private ImageFormat _Format;
    public ImageType()
        : this(ImageFormat.Bmp) { }
    private ImageType(ImageFormat Format)
        : base(new BinarySqlType())
    {
        _Format = Format;
    }
    private byte[] ImageToBytes(object Value)
    {
        Image val = Value as Image;
        if (val == null)
            return null;
        else
        {
            using (MemoryStream stream = new MemoryStream())
            {
                val.Save(stream, _Format);
                return stream.ToArray();
            }
        }
    }
    private Image BytesToImage(object Value)
    {
        byte[] val = Value as byte[];
        if (val == null)
            return null;
        else
        {
            using (MemoryStream stream = new MemoryStream(val))
            {
                return Image.FromStream(stream);
            }
        }
    }
    public override object DeepCopyNotNull(object val)
    {
        return BytesToImage(NHibernateUtil.Binary.DeepCopyNotNull(ImageToBytes((Image)val)));
    }
    public override object FromStringValue(string xml)
    {
        return BytesToImage((byte[])NHibernateUtil.Binary.FromStringValue(xml));
    }
    public override object Get(IDataReader rs, string name)
    {
        return Get(rs, rs.GetOrdinal(name));
    }
    public override object Get(IDataReader rs, int index)
    {
        return BytesToImage((byte[])NHibernateUtil.Binary.Get(rs, index));
    }
    public override void Set(IDbCommand cmd, object value, int index)
    {
        NHibernateUtil.Binary.Set(cmd, ImageToBytes((Image)value), index);
    }
    public override string ToString(object val)
    {
        return NHibernateUtil.Binary.ToString(ImageToBytes((Image)val));
    }
    public override bool Equals(object x, object y)
    {
        return NHibernateUtil.Binary.Equals(
            (x is Image ? ImageToBytes((Image)x) : (byte[])x),
            (y is Image ? ImageToBytes((Image)y) : (byte[])y));
    }
    public override string Name
    {
        get { return "Image"; }
    }
    public override Type ReturnedClass
    {
        get { return typeof(Image); }
    }
}
Cheers