记一次制作潘通色卡TPG电子版的心路历程

第一次尝试解析TCX
第二次尝试解析TPG
第三次一次到位TCX&TPG

前言

近期规划遇到一个需求,项目中所用颜色需要使用潘通色卡上的颜色,他们给我一套某宝购买的色卡集(共计2625个潘通色)以作参考,长这样

在这里插入图片描述
在与公司纺织专业的同事沟通过后,了解到他们为了工作方便,还有一个扫码枪,扫一下色卡或布料,就能得到色块信息,神奇~
在这里插入图片描述
通过数小时的研究,总结出色卡上的关键信息有

类型含义
Color Nr.潘通色号
Name颜色名字
Book在哪本色卡集
Page在哪一页
Row在哪一行
Hex Code16进制颜色值 (未印制在色卡上)
RGB10进制颜色值 (未印制在色卡上)

参考的网站:

  1. 潘通·国际
  2. 潘通·中国
  3. Torso

正文

一 、收集资料

1. 翻阅潘通·国际

潘通·国际上看到有FIND A PANTONE COLOR,如果我猜得没错的话,这个可以查找官方提供的潘通色在这里插入图片描述注册免费账号(不要钱的就是香)在这里插入图片描述通过一番摸索,终于在Color选项找到了查找潘通色的入口在这里插入图片描述设置到对应选项 FHI Paper TPG在这里插入图片描述右侧设置竟还能设置色块布局(这个设计很友好嘛)在这里插入图片描述看到上面结果的时候,我的内心狂喜,心想这需求很简单嘛,马上搞定。
BUT!很快我就发现,潘通官网在这里设置了障碍。F12查看网页源代码,并没有发现关于任何关于色块的html代码,卒~在这里插入图片描述好消息是无意间点击色块,在弹出框中选择GET PHYSICAL SAMPLE,发现一个可以根据色号查询色号信息的接口(https://www.pantone.com/connect/
在这里插入图片描述在这里插入图片描述

2. 翻阅潘通·中国

国际网找不到,那么就在潘通·中国找寻PANTONE色彩查找TPG在这里插入图片描述在这里插入图片描述但只搜到了2310个结果,与色卡上的2625还差315个潘通色。
不过,有比没有强,先把搜索到的内容格式化存储到文本。F12查看网页源代码,找到色块所在DOM,复制元素到txt文档。
在这里插入图片描述
将字符串赋值到js文件中的一个变量在这里插入图片描述分析html代码,提取关键信息data-color-codedata-hex-codestyle:background-color,这里用正则表达式最方便了

<script>
  const colorCodeRegx =  /(data-color-code)=[^\s][^"]+/gi;
  const hexCodeRegx =  /(data-hex-code)=[^\s>]+/gi;
  const colorRegx =  /<div\s[^>]*style=\"([^">]+)\"[^>]*>/ig;

  const listOfColorCode = str.match(colorCodeRegx);
  const listOfHexCode = str.match(hexCodeRegx);
  const listOfColor = str.match(colorRegx);
  
  const listOfResult = listOfColor.map((item, index) => {
    return {
      color_code: listOfColorCode[index].match(/(?<=data-color-code\=").+/ig)[0],
      hex_code: listOfHexCode[index].match(/(?<=data-hex-code\=").+[^"]/ig)[0],
      rgb: item.match(/(?<=rgb\().+(?=\);")/ig)[0]
    }
  });
  console.log(JSON.stringify(listOfResult));
</script>

将匹配后的格式化文本粘贴到txt文档。在这里插入图片描述接下来就是考虑新增的那315个色号怎么整了。。。

3. 探索Torso

继续搜索,一番操作后,发现一个神奇的网站Torso,竟然可以下载潘通色卡的目录PDF。在这里插入图片描述最最神奇的是该目录包含2020年完整的2625个色号,以及新增哪些色号(绿色标注)。在这里插入图片描述

二、分析现有资料

1. 我有什么?

2310个色号信息(来源:潘通·中国)、2625个色号的目录(来源:Torso)、色号查询接口(来源:潘通·国际)

2. 我能做什么?

将已有的2310个色号信息添加到对应目录中;对于新增的315个色号,可以通过色号查询接口按照色号进行查询。

三、工程实施

1. 格式化2310个数据信息

public struct PantoneInfo
{
    public string color_code;
    public string hex_code;
    public string rgb;
}
PantoneInfo[] pantoneInfos;
public void ReadTPGColor()
{
    using (FileStream fs = new FileStream("TPGColor2310.txt", FileMode.Open, FileAccess.Read))
    {
        StreamReader reader = new StreamReader(fs, Encoding.UTF8);
        pantoneInfos = JsonConvert.DeserializeObject<PantoneInfo[]>(reader.ReadLine().Trim());
        reader.Close();
        fs.Close();
    }
}

2. 根据色号查询信息

void GetColorFromRequest(string ColorNr, ref string hex_code, ref string rgb)
{
    try
    {
        WebRequest request = WebRequest.Create("https://www.pantone.com/connect/" + ColorNr);
        WebResponse response = request.GetResponse();
        Stream receiveStream = response.GetResponseStream();

        StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
        //获取网页源代码
        string html = reader.ReadToEnd();
        reader.Close();
        receiveStream.Close();
        response.Close();

        int resultIndex = html.IndexOf("window.pageDataJson = ");
        int startIndex = html.IndexOf("{", resultIndex);
        int endIndex = html.IndexOf("};", startIndex);
        string jsonStr = html.Substring(startIndex, endIndex - startIndex + 1);

        JObject jsonData = JsonConvert.DeserializeObject(jsonStr) as JObject;
        JObject colorJsonData = JsonConvert.DeserializeObject(jsonData["color"].ToString()) as JObject;
        JObject hexJsonData = JsonConvert.DeserializeObject(colorJsonData["hex"].ToString()) as JObject;
        JObject rgbJsonData = JsonConvert.DeserializeObject(colorJsonData["rgb"].ToString()) as JObject;

        hex_code = hexJsonData["HTML"].ToString();
        rgb = $"{rgbJsonData["Red"]},{rgbJsonData["Green"]},{rgbJsonData["Blue"]}";
    }
    catch (Exception e)
    {
        CLog.LogLine(CLog.LogType.Log, "");
        CLog.LogLine(CLog.LogType.Error, $"[ERROR] Get Nr.{ColorNr} Failed! -- {e.Message}");
        hex_code = "";
        rgb = "";
    }
}

3. 数据化目录pdf

将在Torso上下载的pdf文档中的信息复制到txt文档,分析文本格式,读取已有的2310个色号信息,数据化目录

public struct PantoneInfoWithPageRow
{
    public string nr;
    public string name;
    public int book;
    public int page;
    public int row;
    public string hexCode;
    public string rgb;
}
List<PantoneInfoWithPageRow> pantoneInfoWithPageRows = new List<PantoneInfoWithPageRow>(2625);
List<PantoneInfoWithPageRow> sorted;
public void FormatOriginTxt()
{
    string lineStr = "";
    using (FileStream readFS = new FileStream("PantoneColor.txt", FileMode.Open, FileAccess.Read))
    {
        StreamReader reader = new StreamReader(readFS, Encoding.UTF8);

        string ColorNr, Name, Book, Page, Row, HexCode = "", RGB = "", Update;
        int arrLen, index;
        string[] lineArray;
        string[] nameArray;

        CLog.LogLine(CLog.LogType.Log, $"-------------------------------------------------------");
        while (reader.Peek() != -1)
        {
            ColorNr = Name = Book = Page = Row = HexCode = RGB = Update = "";
            arrLen = index = -1;
            lineArray = nameArray = null;

            lineStr = reader.ReadLine().Trim();
            if (!string.IsNullOrEmpty(lineStr))
            {
                lineArray = lineStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                arrLen = lineArray.Length;

                ColorNr = lineStr.Substring(0, 19);

                ClearCurrentConsoleLine();
                CLog.Log(CLog.LogType.Log, $"Processing  ColorNr: {ColorNr}");

                nameArray = new string[arrLen - 10];
                for (int i = 0; i < arrLen - 10; i++)
                {
                    nameArray[i] = lineArray[i + 3];
                }
                Name = CombineStringWithUpperFirst(" ", nameArray);
                Book = lineArray[arrLen - 7];
                Page = lineArray[arrLen - 6].Substring(2, 3);
                Row = lineArray[arrLen - 5];
                //1.New Color   2.No Change   3.New Page
                Update = CombineStringWithUpperFirst(" ", lineArray[arrLen - 2], lineArray[arrLen - 1]);
                
                //根据Update的值判断如何对hexCode和rgb赋值
				if (Update.Equals("New Color"))
                {
                	//把色号传入查询接口
                    GetColorFromRequest(ColorNr.Substring(8, 11), ref HexCode, ref RGB);
                }
                else
                {
                	//根据色号取值
                    index = FindColorInfoWithNr(ColorNr);
                    if (index == -1)
                    {
                        HexCode = "";
                        RGB = "";
                    }
                    else
                    {
                        HexCode = pantoneInfos[index].hex_code;
                        RGB = pantoneInfos[index].rgb;
                    }
                }
                
                pantoneInfoWithPageRows.Add(new PantoneInfoWithPageRow()
                {
                    nr = ColorNr,
                    name = Name,
                    book = int.Parse(Book),
                    page = int.Parse(Page),
                    row = int.Parse(Row),
                    hexCode = HexCode,
                    rgb = RGB
                });
            }
        }

        //关闭文件流
        reader.Close();
        readFS.Close();
        CLog.LogLine(CLog.LogType.Log, "");
        CLog.LogLine(CLog.LogType.Log, "-------------------------------------------------------");
    }
}
//根据色号在已有的2310个色号中查找信息
int FindColorInfoWithNr(string name)
{
    for (int i = 0; i < pantoneInfos.Length; i++)
    {
        if (name.Contains(pantoneInfos[i].color_code))
        {
            return i;
        }
    }
    return -1;
}
//连接字符串 “New”、“Color” --> “New Color”
string CombineStringWithUpperFirst(string combineChar, params string[] str)
{
    if (str.Length == 0)
    {
        return "";
    }
    string tmp = "";
    for (int i = 0; i < str.Length - 1; i++)
    {
        tmp += ToUpperFirst(str[i]) + combineChar;
    }
    tmp += ToUpperFirst(str[str.Length - 1]);
    return tmp;
}
//首字母大写
unsafe string ToUpperFirst(string str)
{
    if (str == null) return null;
    string ret = string.Copy(str);
    fixed (char* ptr = ret)
    {
        *ptr = char.ToUpper(*ptr);
    }

    return ret;
}

4. 对数据化的色号目录进行排序(Book、Page、Row均由大到小)

List<PantoneInfoWithPageRow> sorted;
public void PageSort()
{
    int index = -1;

    int book = 2;
    int page = 200;
    int row = 7;

    int count = pantoneInfoWithPageRows.Count;
    sorted = new List<PantoneInfoWithPageRow>();
    for (int i = 0; i < count; i++)
    {
        ClearCurrentConsoleLine();
        CLog.Log(CLog.LogType.Log, $"Processing  Book: {book}  Page: {page}  Row:  {row}");

        while (true)
        {
            index = FindPageRowWithBook(book, page, row);
            if (index == -1)
            {
                row--;
                if (row == 0)
                {
                    row = 7;
                    page--;
                    if (page == 0)
                    {
                        page = 200;
                        row = 7;
                        book--;
                        if (book == 0)
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                break;
            }
        }
        if (index != -1)
        {
            sorted.Add(pantoneInfoWithPageRows[index]);

            row--;
            if (row == 0)
            {
                row = 7;
                page--;
                if (page == 0)
                {
                    row = 7;
                    page = 200;
                    book--;
                    if (book == 0)
                    {
                        break;
                    }
                }
            }
        }
    }
    CLog.LogLine(CLog.LogType.Log, "");
}

5. 逆序后输出最终文档

public void WriteSortedFile()
{
    using (FileStream writeFS = new FileStream("PantoneColorFormatPageRow.txt", FileMode.Create, FileAccess.Write))
    {
        StreamWriter writer = new StreamWriter(writeFS, Encoding.UTF8);

        writer.WriteLine(string.Format("{0,-13}{1,-25}{2,-20}{3,-10}{4,-10}{5,-10}{6,-10}{7,-10}", "Number", "Color Nr.", "Name", "Book", "Page", "Row", "Hex Code", "RGB"));

        int count = sorted.Count;
        sorted.Reverse();
        for (int i = 0; i < count; i++)
        {
            writer.WriteLine(string.Format("No.{0,-10:D4}{1,-25}{2,-20}{3,-10}{3}.{4,-8:D3}{5,-10}{6,-10}{7,-10}",
                i + 1,
                sorted[i].nr,
                sorted[i].name,
                sorted[i].book,
                sorted[i].page,
                sorted[i].row,
                sorted[i].hexCode,
                sorted[i].rgb.Replace(" ", "")));
        }

        writer.Flush();
        writer.Close();
        writeFS.Close();

        CLog.LogLine(CLog.LogType.Log, "Write Over! Press Any Key To Continue!");
    }
}

在这里插入图片描述
在这里插入图片描述

总结

遇到新需求还是不能太掉以轻心,应多收集资料,将资料汇总后,找到之前的关系,合理利用。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jack_dos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值