Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a440496
feat: Add extensive type annotations, add classes for path handling, …
pappnu Aug 12, 2025
a2b308f
fix(Layer): return parent with correct type
pappnu Aug 13, 2025
2089887
fix(LayerSet): fix iterating LayerSet object directly
pappnu Aug 13, 2025
6d7429f
test(TestNewDocument): test getting layer parent and expand layer ite…
pappnu Aug 13, 2025
121328a
feat: add py.typed file to indicate that the package contains type an…
pappnu Aug 13, 2025
94d4344
fix(executeActionGet): correct input argument type
pappnu Aug 13, 2025
a8dedc4
fix(Application): executeAction can be called without an ActionDescri…
pappnu Aug 14, 2025
0b975b9
fix(Select): select takes an array of four coordinates
pappnu Aug 14, 2025
9d8de09
style: Format and sort imports
pappnu Aug 15, 2025
1a7b953
feat(Layer): Add default value to rotate anchor
pappnu Aug 15, 2025
e790d52
fix(Documents): Document width and height can be given as floats, tho…
pappnu Aug 16, 2025
9f8496e
fix(path_item.py): Import TYPE_CHECKING from typing instead of errone…
pappnu Aug 26, 2025
15309e3
refactor: Avoid unnecessary getattribute calls to the wrapper objects
pappnu Feb 15, 2026
22a673d
test(manual_test_new_document.py): Add tests for layer querying
pappnu Feb 15, 2026
f6c72c3
feat: Bump Python requirement to >=3.10, modernize pyproject.toml, up…
pappnu Feb 15, 2026
cee5fe1
docs(README.md): Instruct how to browse the COM API with Visual Studio
pappnu Feb 15, 2026
4430335
fix(Selection): Selection's select can take a sequence of more than f…
pappnu Feb 22, 2026
4acf07c
fix(FontSize): Don't use StrEnum as Python 3.10 doesn't have it
pappnu Feb 25, 2026
53965a6
fix(Notifiers): Access the Photoshop Application object correctly
pappnu Feb 25, 2026
4cd7f34
feat(Photoshop): Allow accessing the Photoshop Application object fro…
pappnu Feb 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/import-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
max-parallel: 3
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12"]

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pythonpackage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
max-parallel: 3
matrix:
python-version: ["3.8", "3.9", "3.10"]
python-version: ["3.10"]

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
Expand Down
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
language: python
python:
- "3.8"
- "3.9"
- "3.10"
before_script:
- pip install poetry
Expand Down
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ Useful links
- http://shining-lucy.com/wiki/page.php?id=appwiki:photoshop:ps_script
- http://web.archive.org/web/20140121053819/http://www.pcpix.com/Photoshop/char.html
- http://www.tonton-pixel.com/scripts/utility-scripts/get-equivalent-id-code/index.html
- https://github.com/Adobe-CEP/CEP-Resources/tree/master/Documentation/Product%20specific%20Documentation/Photoshop%20Scripting
- https://github.com/Adobe-CEP/Samples/tree/master/PhotoshopEvents
- https://evanmccall.wordpress.com/2015/03/09/how-to-develop-photoshop-tools-in-python

Expand Down Expand Up @@ -279,7 +280,7 @@ We value thorough testing to ensure reliability:

### 📦 Development Environment

- **Python Versions**: We support Python 3.8+ (see `pyproject.toml` for specifics)
- **Python Versions**: We support Python 3.10+ (see `pyproject.toml` for specifics)
- **Dependency Management**: [Poetry](https://python-poetry.org/) for consistent environments
- **Virtual Environment**: Poetry automatically creates and manages virtual environments

Expand All @@ -295,3 +296,18 @@ We value thorough testing to ensure reliability:
8. **Merge**: Once approved, your PR will be merged

Thank you for contributing to the Photoshop Python API project! 🎉

### Development Notes

One way to view the COM API structure is to use Visual Studio.

1. Install Visual Studio with the .NET desktop development workload
2. Open Visual Studio
3. Choose View -> Object Browser
4. In the Object Browser from the Browse dropdown choose *Edit Custom Component Set...*
5. In the Edit Custom Component Set window's COM tab add Photoshop's Object and Type libraries
6. After pressing OK the libraries should show up in the Object Browser

If the libraries aren't visible in the COM tab make sure you have the .NET desktop development workload installed. Other things you may try are running Photoshop once as administrator and reinstalling Photoshop and/or your PC. The object library is defined usually in */your/path/to/Adobe Photoshop \<version\>/Required/Plug-ins/Extensions/ScriptingSupport.8li*

The [VBS reference 2020](https://github.com/Adobe-CEP/CEP-Resources/blob/master/Documentation/Product%20specific%20Documentation/Photoshop%20Scripting/photoshop-vbs-ref-2020.pdf) is also quite trustworthy, since Adobe isn't actively developing the COM API anymore.
4 changes: 2 additions & 2 deletions examples/active_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
docRef.artLayers.add()

# Display current active layer name
ps.echo(docRef.activeLayer.name)
print(docRef.activeLayer.name)

# Create and rename a new layer
new_layer = docRef.artLayers.add()
ps.echo(new_layer.name)
print(new_layer.name)
new_layer.name = "test"
2 changes: 1 addition & 1 deletion examples/add_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
doc.info.provinceState = "Beijing"
doc.info.title = "My Demo"
print("Print all metadata of current active document.")
ps.echo(doc.info)
print(doc.info)
4 changes: 2 additions & 2 deletions examples/change_color_of_background_and_foreground.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@
ps.app.backgroundColor = bg_color

# Print current colors
ps.echo(f"Foreground RGB: {ps.app.foregroundColor.rgb.red}, "
print(f"Foreground RGB: {ps.app.foregroundColor.rgb.red}, "
f"{ps.app.foregroundColor.rgb.green}, "
f"{ps.app.foregroundColor.rgb.blue}")

ps.echo(f"Background RGB: {ps.app.backgroundColor.rgb.red}, "
print(f"Background RGB: {ps.app.backgroundColor.rgb.red}, "
f"{ps.app.backgroundColor.rgb.green}, "
f"{ps.app.backgroundColor.rgb.blue}")
2 changes: 1 addition & 1 deletion examples/compare_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@
color1.rgb.green == color2.rgb.green and
color1.rgb.blue == color2.rgb.blue)

ps.echo(f"Colors are {'same' if is_same else 'different'}")
print(f"Colors are {'same' if is_same else 'different'}")
6 changes: 3 additions & 3 deletions examples/convert_smartobject_to_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@

# Convert to smart object
layer.convertToSmartObject()
ps.echo("Layer converted to Smart Object")
print("Layer converted to Smart Object")

# Check if it's a smart object
if layer.kind == ps.LayerKind.SmartObjectLayer:
ps.echo("Layer is now a Smart Object")
print("Layer is now a Smart Object")

# Convert back to regular layer
layer.rasterize(ps.RasterizeType.EntireLayer)
ps.echo("Smart Object converted back to regular layer")
print("Smart Object converted back to regular layer")
2 changes: 1 addition & 1 deletion examples/current_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
current = ps.app.currentTool

# Print current tool name
ps.echo(f"Current tool: {current}")
print(f"Current tool: {current}")
2 changes: 1 addition & 1 deletion examples/eval_javascript.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@
# Execute JavaScript command
js_code = "app.documents.length"
result = ps.app.eval_javascript(js_code)
ps.echo(f"Number of open documents: {result}")
print(f"Number of open documents: {result}")
2 changes: 1 addition & 1 deletion examples/export_layers_use_export_options_saveforweb.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def main():
image_path = os.path.join(layer_path, f"{layer.name}.png")
doc.exportDocument(image_path, exportAs=ps.ExportType.SaveForWeb, options=options)
ps.alert("Task done!")
ps.echo(doc.activeLayer)
print(doc.activeLayer)


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions examples/get_document_by_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# Try to get document named 'test.psd'
for doc in ps.app.documents:
if doc.name == "test.psd":
ps.echo(doc.name)
print(doc.name)
break
else:
ps.echo("Document not found!")
print("Document not found!")
2 changes: 1 addition & 1 deletion examples/get_layer_by_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@
doc = ps.app.activeDocument
for layer in doc.layers:
if layer.name == "example layer":
ps.echo(layer.name)
print(layer.name)
break
6 changes: 3 additions & 3 deletions examples/link_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@
layer2.link(layer3)

# Check link status
ps.echo(f"Layer 1 linked: {layer1.linked}")
ps.echo(f"Layer 2 linked: {layer2.linked}")
ps.echo(f"Layer 3 linked: {layer3.linked}")
print(f"Layer 1 linked: {layer1.linked}")
print(f"Layer 2 linked: {layer2.linked}")
print(f"Layer 3 linked: {layer3.linked}")

# Move linked layers together
layer1.translate(100, 100)
4 changes: 2 additions & 2 deletions examples/load_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,5 @@
doc.selection.combine(doc.channels[-1], ps.SelectionType.ExtendSelection)

# Clean up - delete added channels
doc.channels[-1].remove()
doc.channels[-1].remove()
doc.channels[-1].delete()
doc.channels[-1].delete()
2 changes: 1 addition & 1 deletion examples/open_psd.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

# style 2
with Session("your/psd/or/psb/file_path.psd", action="open") as ps:
ps.echo(ps.active_document.name)
print(ps.active_document.name)
2 changes: 1 addition & 1 deletion examples/operate_channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

# List all channels
for channel in doc.channels:
ps.echo(f"Channel: {channel.name}")
print(f"Channel: {channel.name}")

# Create a new alpha channel
new_channel = doc.channels.add()
Expand Down
4 changes: 2 additions & 2 deletions examples/operate_layerSet.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@

# List layers in groups
for layer in main_group.layers:
ps.echo(f"Layer in main group: {layer.name}")
print(f"Layer in main group: {layer.name}")

for layer in sub_group.layers:
ps.echo(f"Layer in sub group: {layer.name}")
print(f"Layer in sub group: {layer.name}")

# Move a layer between groups
layer1.move(sub_group, ps.ElementPlacement.INSIDE)
2 changes: 1 addition & 1 deletion examples/session_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ def on_close():


with Session(callback=on_close) as ps:
ps.echo("Working in session...")
print("Working in session...")
2 changes: 1 addition & 1 deletion examples/session_new_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@


with Session(action="new_document") as ps:
ps.echo(ps.active_document.name)
print(ps.active_document.name)
18 changes: 0 additions & 18 deletions photoshop/api/_active_layer.py

This file was deleted.

Loading
Loading