likes
comments
collection
share

Photopshop 中的文字解析及其在前端的应用

作者站长头像
站长
· 阅读数 22

背景

在笔者负责的营销活动项目中,不同时间和场景需要不同的文案图片,传统方式下,设计需求需要多次沟通后设计师才能修改文案并提供图片。但借助 Photoshop 插件 (下面简称 CEP),设计师可以创建模板并将文字样式和背景图片解析,让运营人员在在线编辑器上修改文案,提高工作效率。本文将探讨如何利用 Photoshop 插件进行文字样式解析,实现精准的设计还原。

Photoshop 插件 (CEP) 是什么

CEP 是 Adobe 为 Photoshop 等软件提供的扩展平台,使用 HTML5 和 Node.js 技术扩展 Adobe 系列软件功能。简单来说,它是通过一个本地 Web 应用调用 Node.js 和 Photoshop 提供的 JavaScript API 来扩展 Photoshop 的能力。本文将介绍如何利用 CEP 实现文字样式解析。

CEP 开发环境搭建

快速搭建开发环境,有两种方式,一是在官方提供 demo 的基础开发,还有一种脚手架 (bolt-cep) 生成工程化的开发环境 (极力推荐)。

不管你采用哪种方式,都需要安装插件,其实就是放置在 PS 的某个路径下的一个文件夹,里头包含了必备需要的文件。具体安装方式,可以参考 imgcook Photoshop 插件手动安装,我们直接将 CSXS 的父级文件夹导出到对应位置即可。

另外,如果你不想将开发项目存放到 ps 指定的文件夹下,可以通过软链的方式,下面是 MacOS 写法:

# cep:CSXS的父级文件夹
# /Library/Application\ Support/Adobe/CEP/extensions:PS插件安装的路径
ln -s cep /Library/Application\ Support/Adobe/CEP/extensions

文字样式解析

文字样式比较多,比如 lineHeight、fontSize、Shadow、matrix、Stroke...

我们通过 Action Manager 方式来解析文字。Action Manager 是 Photoshop 的编程接口,允许使用 JavaScript 执行各种操作,例如创建图层、调整图层属性等。比如通过 Action Manager 选中为图层名为 “Hello,World!” 的图层。

// 创建一个新的动作
var ref1 = new ActionReference();
ref1.putName(stringIDToTypeID('layer'), 'Hello, World!');

// 设置动作描述
var desc1 = new ActionDescriptor();
desc1.putReference(stringIDToTypeID('null'), ref1);

// 执行动作
executeAction(stringIDToTypeID('select'), desc1, DialogModes.NO);

Action Manager 的入门可以参考 Action Manager 从好奇到劝退

现在我们来获取文字的 color、fontSize、Shadow,其他的可以类比获取了

本次解析的文字如下,“每天最高多赚 888 元”:

Photopshop 中的文字解析及其在前端的应用

想要解析该文字,需要通过代码获取该图层的 ActionDescriptor,为了快速获取,我们先手动选中该图层

Photopshop 中的文字解析及其在前端的应用

通过代码获取图层的 ActionDescriptor

// 获取当前被选中图层的 ActionDescriptor
const getSelectedLayerDesc = () => {
  // 创建一个ActionReference对象,用于指定要执行操作的目标图层
  const layerReference = new ActionReference();
  // 创建一个ActionDescriptor对象,用于存储操作的参数
  const getDescriptor = new ActionDescriptor();
  // 将目标图层的类型设置为“layer”,并指定获取选中图层
  layerReference.putEnumerated(
    stringIDToTypeID('layer'),
    stringIDToTypeID('ordinal'),
    stringIDToTypeID('targetEnum'),
  );
  // 将ActionReference对象添加到ActionDescriptor中,以指定要执行操作的图层
  getDescriptor.putReference(app.stringIDToTypeID('null'), layerReference);
  // 执行获取选中图层描述的操作,并返回当前选中图层的ActionDescriptor
  return app.executeAction(
    app.charIDToTypeID('getd'),
    getDescriptor,
    DialogModes.NO,
  );
};

获取 color

当你将 Action Manager 从好奇到劝退上中下三篇看完之后,你就会发现获取文字样式,就是就是通过 ActionDescriptor 去获取对应的属性而已,我们可以借助脚本辅助工具获取各个属性所在位置,然后通过 ActionDescriptor 来获取。比如下面我们想要获取 color

{
  "name": "每天最高多赚888元",
  "layerEffects": {
    "dropShadow": {
      "enabled": true,
      "color": {
        "red": 43.9993286132812,
        "grain": 173.001251220703,
        "blue": 253.000030517578
      },
      "opacity": 29,
      "distance": 6
    }
  },
  "textKey": {
    "textKey": "每天最高多赚888元",
    "textStyleRange": [
      {
        "textStyleRange": {
          "textStyle": {
            "fontPostScriptName": "FZLTZHJW--GB1-0",
            "size": 54,
            "impliedFontSize": 54,
            "syntheticItalic": false,
            "syntheticBold": false,
            "color": {
              "red": 255,
              "grain": 255,
              "blue": 255
            }
          }
        }
      }
    ]
  }
}
// 获取当前被选中图层的ActionDescriptor
const desc = getSelectedLayerDesc();
// 获取第一层textKey,它是Object类型,因此需要用desc.getObjectValue获取
const textKeyDesc = desc.getObjectValue(app.stringIDToTypeID('textKey'));
// 获取 textStyleRange,他是一个数组 因此需要用 textKeyDesc.getList 获取
const textStyleRanges = textKeyDesc.getList(
  app.stringIDToTypeID('textStyleRange'),
);
// 获取样式描述,textStyleRanges.getObjectValue(0) 代表获取数组中第一个对象
const styleDesc = textStyleRanges
  .getObjectValue(0)
  .getObjectValue(app.stringIDToTypeID('textStyle'));
// 这里获取的是 对象{"red": 255,"grain": 255,"blue": 255}
const colorDesc = styleDesc.getObjectValue(app.stringIDToTypeID('color'));
// 转成rgb
const red = colorDesc.getDouble(app.stringIDToTypeID('red'));
const green = colorDesc.getDouble(app.stringIDToTypeID('grain'));
const blue = colorDesc.getDouble(app.stringIDToTypeID('blue'));

return `rgb(${red},${green},${blue})`;

获取 fontSize

// 按照获取color的方式获取 styleDesc
const fontSize = styleDesc.getDouble(app.stringIDToTypeID('size'));

这里需要注意的是,fontSize 是 Double 类型,而不是 int 类型,另外要注意的是,size、impliedFontSize 的区别,

impliedFontSize 是当前文字在 ps 渲染的大小,size 是实际大小,这两个在文字斜切等相关处理的时候,就会产生差异,如果想要在浏览器根据 CEP 提供的 transform 还原的话,需要使用 size。

获取 Shadow

Shadow、Stroke、Filling 等并不在 styleDesc 中,而是在 layerEffects 中。我们拿 Shadow 来说。

Shadow 是对应的 dropShadow

// 获取当前被选中图层的 ActionDescriptor
const desc = getSelectedLayerDesc();
// 获取 layerEffects 的 ActionDescriptor
const layerEffects = descriptor.getObjectValue(
  app.stringIDToTypeID('layerEffects'),
);
// 获取 dropShadow 的 ActionDescriptor
const dropShadowDesc = layerEffects.getObjectValue(
  app.stringIDToTypeID('dropShadow'),
);
// 获取 enabled,为true的时候,打标有阴影,否则未开启阴影,不做后面的解析了,我们这里默认开启了
const enabled = dropShadowDesc.getBoolean(app.stringIDToTypeID('enabled'));

const blur = dropShadowDesc.getDouble(app.stringIDToTypeID('blur'));
const offsetX = dropShadowDesc.getDouble(app.stringIDToTypeID('distance'));
const offsetY = dropShadowDesc.getDouble(app.stringIDToTypeID('distance'));
const opacity = desc.getDouble(app.stringIDToTypeID('opacity'));
const colorDesc = dropShadowDesc.getObjectValue(app.stringIDToTypeID('color'));

// 转成rgba
const red = colorDesc.getDouble(app.stringIDToTypeID('red'));
const green = colorDesc.getDouble(app.stringIDToTypeID('grain'));
const blue = colorDesc.getDouble(app.stringIDToTypeID('blue'));
const alpha = ((opacity ?? 100) / 100) * 255;
const color = `rgb(${red},${green},${blue}),${opacity}`;

return { color, blur, offsetX, offsetY };

你可以尝试去解析剩下的样式了。

效果演示

解析了图层信息后,使用 CSS 和 HTML 在线还原设计稿。

Photopshop 中的文字解析及其在前端的应用

总结

这期主要讲解简单的文字解析,其实现流程:获取当前文字图层的 ActionDescriptor → 使用脚本辅助工具获取需要解析属性的位置 → 根据 ActionDescriptor 提供获取属性的 API 获取对应的属性。

总的来说,以上内容仍处于摸索阶段,需要进一步的研究和实践。如果有任何不妥之处,欢迎指正,共同进步。🙏🙏🙏

转载自:https://juejin.cn/post/7365879319597416460
评论
请登录