Skip to content

Instantly share code, notes, and snippets.

@oiehot oiehot/composite.py
Created Oct 1, 2017

Embed
What would you like to do?
Building Photoshop layers with Python
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)
@wizofe

This comment has been minimized.

Copy link

wizofe commented Mar 1, 2019

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.

@smerkousdavid

This comment has been minimized.

Copy link

smerkousdavid commented Jul 23, 2019

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 :/

@josephernest

This comment has been minimized.

Copy link

josephernest commented Nov 1, 2019

@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

This comment has been minimized.

Copy link
Owner Author

oiehot commented Nov 2, 2019

@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");
@josephernest

This comment has been minimized.

Copy link

josephernest commented Nov 2, 2019

Thank you very much @oiehot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.