昨日, 一老友突然发个信息问在没, 有事, 当时一紧张, 想到底应该说在还是不在呢?接着又来了几句说会不会PS, 还好这位朋友没有问我会不会修电脑, 心理顿时欣慰了。 就勉强问要P啥(心理完全没底, 几年没安装过PS了, 就大学学了几个皮毛), 沟通后, 知道是要修改图片上的文字, 感觉还好, 瞎搞瞎搞就能弄出来了。
一张图大概7, 8个地方需要修改, 修改下来已经累觉不爱了, 特别是字体大小, 位置, 颜色等, 太费时间了。 被告知会有50, 60个需要修改的, 顿时感觉压力山大了, 心理想PhotoShop会不会有什么机制能支持这种重复 繁杂的工作呢?了解到PhotoShop是支持脚本的, 感觉看到一些希望了。
// 当前选中的文档
var doc = app.activeDocument;
// 白色
var white = new SolidColor();
white.rgb.red = 255;
white.rgb.green = 255;
white.rgb.blue = 255;
// 文本颜色
var textColor = new SolidColor();
textColor.rgb.red = 47;
textColor.rgb.green = 48;
textColor.rgb.blue = 48;
// 擦除某个区域
var erase = function(pos){
doc.selection.select(pos); //选择文档的某个区, 分别为左上, 右上, 右下, 左下四个点的(x, y)坐标
doc.selection.fill(white); //填充为白色
doc.selection.deselect(); //取消选择
}
// 填充文本
var text = function(pos, font, color, size, contents){
var eraseLayer = doc.artLayers.add(); // 添加图层
eraseLayer.kind = LayerKind.TEXT; // 设置图层为文本类型
var textItem = eraseLayer.textItem;
textItem.font = font; // 字体, 如 "SimSun"(宋体)
textItem.color = color;
textItem.size = size; // 字体大小(points)
textItem.contents = contents; // 文本内容
textItem.position = pos; // 文本位置
doc.mergeVisibleLayers(); // 合并文档所有可见的图层
}
// 假如我们要修改某个区域, 则可以定义一个函数
var patchPayDate = function(){
erase(Array(Array(930, 125), Array(1400, 125), Array(1400, 175), Array(930, 175)));
text(Array(940, 170), "SimSun", textColor, 11, payDate);
}
patchPayDate();
1. 中文支持: 必须设置字体, 否则中文乱码textItem.font="SimSum"
2. 执行下次操作前合并图层doc.mergeVisibleLayers(), 否则不能继续进行。
3. PS中的矩阵区域表示为: Array(Array(930, 125), Array(1400, 125), Array(1400, 175), Array(930, 175))
4. 文本区域和擦除区域不太吻合: 按理擦除区域即为之后的填充区域, 但实际会有像素偏差, 需要调整。
# 主要代码
import sys
import xlrd, json
import math, random
from xlrd import xldate_as_tuple
def openExcel(file="file.xls"):
try:
return xlrd.open_workbook(file)
except Exception, e:
print str(e)
"""
read a sheet of xls to json
"""
def read2json(file="file.xls", sheetIndex=0, headerIndex=0, startRow=1):
excel = openExcel(file);
sheet = excel.sheets()[sheetIndex];
nrows = sheet.nrows
colnames = sheet.row_values(headerIndex);
facets = []
for rownum in range(startRow, nrows):
row = sheet.row_values(rownum)
if row:
facet = {}
for i in range(len(colnames)):
facet[colnames[i]] = row[i]
facets.append(facet)
return json.dumps(facets, ensure_ascii=False, indent=2)
1. 日期处理: 读取excel时, 读取日期类型后为浮点数, 需要引入xldate_as_tuple进行处理
# 第二个参数表示起始时间: 0: 1900; 1: 1904
# 返回(年, 月, 日, 时, 分, 秒)
dateTuple = xldate_as_tuple(date, 0);
year = dateTuple[0]
month = dateTuple[1]
2. 默认Python使用Ascii进行IO解码, 需要运行时设置
reload(sys)
sys.setdefaultencoding('utf-8')
3. json dump时, 会将中文编码为Ascii, 也需要设置参数json.dumps(facets, ensure_ascii=False, indent=2)
// excel数据
var bills = [{
"payNo": "14009052048",
"businessCategory": "...",
"clerkNo": "00023",
"payerBank": "...",
"payDate": "2014年09月09日",
"tradeCode": "52110",
"payNote": "...",
"printDate": "2014年02月05日",
"payAmount1": "壹万壹仟伍佰贰拾元",
"payAmount2": "11,520.00元",
"printCode": "4N1HTDSPVX2",
"payerNo": "...",
"payerName": "..."
},
...];
var doc = app.activeDocument;
// 修复类
var Patch = function(){
var that = {};
var white = new SolidColor();
white.rgb.red = 255;
white.rgb.green = 255;
white.rgb.blue = 255;
var textColor = new SolidColor();
textColor.rgb.red = 47;
textColor.rgb.green = 48;
textColor.rgb.blue = 48;
var erase = function(pos){
doc.selection.select(pos);
doc.selection.fill(white);
doc.selection.deselect();
}
var text = function(pos, font, color, size, contents){
var eraseLayer = doc.artLayers.add();
eraseLayer.kind = LayerKind.TEXT;
var textItem = eraseLayer.textItem;
textItem.font = font;
textItem.color = color;
textItem.size = size;
textItem.contents = contents;
textItem.position = pos;
doc.mergeVisibleLayers();
}
// 修复日期
var patchPayDate = function(payDate){
erase(Array(Array(930, 125), Array(1400, 125), Array(1400, 175), Array(930, 175)));
text(Array(940, 170), "SimSun", textColor, 11, payDate);
}
// ...其他修复功能
var patch = function(b){
if (!b) return;
if (b.payDate) patchPayDate(b.payDate);
// ...其他修复操作
}
that.patch = patch;
return that;
}();
// 图片保存
var Saver = function(){
var that = {};
// 图片质量
var jpegOptions = new JPEGSaveOptions();
jpegOptions.quality = 8;
var saveAs = function(path){
doc.saveAs(new File(path), jpegOptions);
}
that.saveAs = saveAs;
return that;
}();
// go
for (var i = 0; i<bills.length; i++){
Patch.patch(bills[i]);
Saver.saveAs("~/temp/" + bills[i].payerName + ".jpg");
}
这样基本不需要操作就能完成PS了, 具体可参考 文档。