Created
October 1, 2017 06:15
-
-
Save oiehot/a63782138af5508481f247f40aa0d5f1 to your computer and use it in GitHub Desktop.
Building Photoshop layers with Python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import comtypes.client | |
app = comtypes.client.CreateObject('Photoshop.Application.60') # CS6 | |
# maya config | |
project_path = 'd:/project/alice/maya' | |
log_path = project_path + '/log' | |
images_path = project_path + '/images' | |
layers = ['master', 'prop_matte', 'shadow', 'wall_matte'] | |
passes = ['beauty', 'N'] | |
# psd opt | |
psd_opt = comtypes.client.CreateObject('Photoshop.PhotoshopSaveOptions.60') # CS6 | |
psd_opt.annotations = False | |
psd_opt.alphaChannels = True | |
psd_opt.layers = True | |
psd_opt.spotColors = True | |
psd_opt.embedColorProfile = True | |
def get_image_size(path): | |
doc = app.Open(path) | |
size = (doc.width, doc.height) | |
doc.Close(2) # 2 (psDoNotSaveChanges) | |
return size | |
def copy_file_contents_to_clipboard(path): | |
doc = app.Open(path) | |
doc.layers[0].Copy() | |
doc.Close(2) # 2 (psDoNotSaveChanges) | |
def create_layer_from_file(doc, layer_name, path): | |
copy_file_contents_to_clipboard(path) | |
app.activeDocument = doc | |
layer = doc.artLayers.add() # Create Layer | |
layer.name = layer_name # Rename Layer | |
doc.activeLayer = layer # Select Layer | |
doc.Paste() # Paste into | |
def composite_ma(ma): | |
# 이름 정리 | |
name = os.path.splitext(os.path.basename(ma))[0] # hc_column_corridor | |
path_tokens = os.path.dirname(os.path.abspath(ma)).split('\\') | |
theme = path_tokens[-1] # HeartCastle | |
category = path_tokens[-2] # Housing | |
category_theme = category + '/' + theme # Housing/HeartCastle | |
# 새 포토샵 문서를 만든다 | |
app.Preferences.RulerUnits = 1 # Pixel | |
w, h = get_image_size( images_path + '/' + category_theme + '/' + name + '/masterLayer/beauty.tif' ) # 기본 뷰티를 이용해 그림 크기를 얻는다. | |
doc = app.Documents.Add(w, h, 72, name, 2, 1, 1) | |
app.activeDocument = doc | |
# 파일로 부터 새로운 레이어를 만든다 | |
for layer in layers: | |
create_layer_from_file(doc, layer , images_path + '/' + category_theme + '/' + name + '/' + layer + '/' + 'beauty.tif') | |
# 저장한다 | |
psd_path = images_path + '/' + category_theme + '/' + name + ".psd" | |
print(psd_path) | |
doc.SaveAs(psd_path, psd_opt) | |
doc.Close() | |
def composite(files): | |
for file in files: | |
composite_ma(file) | |
def get_include_list(filepath): | |
f = open(filepath) | |
content = f.readlines() | |
content = [x.strip() for x in content] # 줄 끝에 '\n'를 제거. | |
result = [] | |
for path in content: | |
if path[0] != '#': # 주석 처리된 파일을 생략. | |
result.append(path) | |
return result | |
# main | |
if __name__ == '__main__': | |
files = get_include_list('include.txt') | |
composite(files) |
Well done. Thank you! I love the copy to clipboard hack which actually works for the most part.
For anyone one else who need transparency with a paste in place solution I added a rgba (1, 1, 1, 1) to each corner of the image. Reading Photoshop's documentation I couldn't find a paste in place or with an anchor solution which offset all of my layers depending on the content.
I wish it didn't have to be this hard to add images as layers :/
@oiehot do you know how to Paste(...)
at a specific x,y position? I didn't find how to do it with:
doc.Paste(IntoSelection=...)
@oiehot do you know how to
Paste(...)
at a specific x,y position? I didn't find how to do it with:doc.Paste(IntoSelection=...)
I couldn't find it on the API. However, you can paste it and move it.
function pasteTo(doc, layerName, x, y, pivot) {
oldUnit = app.preferences.rulerUnits;
app.preferences.rulerUnits = Units.PIXELS; // Set to Pixel Unit
app.activeDocument = doc; // Select Document
layer = doc.artLayers.add(); // Create Layer
layer.name = layerName; // Rename Layer
doc.activeLayer = layer; // Select Layer
doc.paste(); // Paset Into Layer
if (pivot == "leftTop") {
translateX = x - Number(layer.bounds[0]);
translateY = y - Number(layer.bounds[1]);
}
else if (pivot == "center") {
centerX = Number(layer.bounds[0] + (layer.bounds[2] - layer.bounds[0]) / 2);
centerY = Number(layer.bounds[1] + (layer.bounds[3] - layer.bounds[1]) / 2);
translateX = x - centerX;
translateY = y - centerY;
}
else {
translateX = 0;
translateY = 0;
}
layer.translate( translateX, translateY );
app.preferences.rulerUnits = oldUnit; // Restore Unit
}
pasteTo(app.activeDocument, "newLayer", 10, 10, "center");
Thank you very much @oiehot!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That is very useful, thanks a lot for posting!
Unfortunately, I can't find any documentation about interfacing Python to Photoshop in detail. It's always a surfing between official Photoshop JS Documentation and experimenting with Python for me.