# PSD to PNG Converter: Render Photoshop Files with Fonts (`scrapers_lat/psd-to-png-converter`) Actor

Convert Photoshop PSD/PSB files to PNG, JPG, WebP or AVIF without Photoshop. Text layers are redrawn with your fonts (upload, link or auto Google Fonts), effects and blend modes applied, layers shown/hidden. Batch + ZIP.

- **URL**: https://apify.com/scrapers_lat/psd-to-png-converter.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Developer tools, Automation, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $42.50 / 1,000 psd converteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

[![PSD to PNG Converter](https://scrapers.lat/banners/psd-to-png-converter.png)](https://console.apify.com/actors/txFkCYClJco4wOSw5/input)

## PSD to PNG Converter: Render Photoshop Files with Fonts

Turn Photoshop documents (**PSD and PSB**) into **PNG, JPG, WebP, AVIF or TIFF** images, in bulk, without Photoshop. Text layers are **redrawn with real fonts**, so text you edited, translated or filled in from a template shows up correctly, even if the file was never re-saved in Photoshop. Adjustment layers, smart objects, every layer effect, blend modes, masks and groups are applied, and you can show or hide any layer before rendering.

**Replace text right here**: translate a design, personalize a template or produce **hundreds of variants from one PSD** with a CSV (one row per image). You can also get back an **edited, still-editable PSD** with the new text.

Missing fonts are handled for you: upload your own, paste links, or let the converter **download the right Google Font automatically** and use **metric-compatible replacements** for Arial, Helvetica, Times New Roman, Calibri and other commercial fonts.

![Summer sale banner rendered from a PSD](https://scrapers.lat/samples/summer-sale-banner.png)

*Rendered from [this sample PSD](https://scrapers.lat/samples/summer-sale-banner.psd) (the prefilled example). Its 6 text layers use Bebas Neue and Poppins, which were not uploaded: the converter found them on Google Fonts by itself.*

**📥 [Input](https://apify.com/scrapers_lat/psd-to-png-converter/input-schema) · 📤 [Output](https://apify.com/scrapers_lat/psd-to-png-converter/output-schema) · 💰 [Pricing](https://apify.com/scrapers_lat/psd-to-png-converter/pricing)**

![Apify](https://img.shields.io/badge/Platform-Apify-1CE1CE?logo=apify\&logoColor=white)
![Input](https://img.shields.io/badge/Input-PSD%20%7C%20PSB%20%7C%20ZIP-blue)
![Output](https://img.shields.io/badge/Output-PNG%20%7C%20JPG%20%7C%20WebP%20%7C%20AVIF-orange)
![Billing](https://img.shields.io/badge/Billing-Pay%20per%20conversion-brightgreen)

### Table of contents

- [What it does](#what-it-does)
- [Who uses it](#who-uses-it)
- [Quickstart](#quickstart)
- [Edit text and fill templates](#edit-text-and-fill-templates)
- [Fonts: how text is matched](#fonts-how-text-is-matched)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Example output record](#example-output-record)
- [Run via API](#run-via-api)
- [Pricing and limits](#pricing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)

### What it does

- **Converts PSD and PSB** files of any size, at 1, 8, 16 and 32 bits per channel, in every color mode: RGB, CMYK, grayscale, bitmap, indexed, Lab, duotone and multichannel.
- **Redraws text layers** from their text, with kerning, tracking, leading, paragraph boxes, every justification mode, indents, all caps and small caps, faux bold and italic, baseline shift, underline and strikethrough. **Vertical text** (including upright CJK) and **OpenType features** such as ligatures, contextual alternates, swashes, fractions, ordinals, oldstyle figures and super/subscript are drawn too. Prefer the pixels Photoshop saved? Switch **Text layers** to *Keep original pixels*.
- **Every warp**: all 15 Photoshop warp styles (Arc, Arch, Bulge, Flag, Wave, Fish, Rise, Fisheye, Inflate, Squeeze, Twist, Shell and the rest) plus custom and quilt warps.
- **Every layer effect**: stroke (solid, gradient or pattern; inside, center or outside), drop shadow, inner shadow, outer glow, inner glow, satin, bevel and emboss (with contours and textures), and color, gradient and pattern overlays.
- **Adjustment layers**: levels, curves, brightness/contrast, hue/saturation, color balance, vibrance, exposure, selective color, channel mixer, gradient map, photo filter, invert, posterize, threshold, black & white and color lookup (3D LUTs).
- **Smart objects**: the preview saved in the file by default, or **re-rendered** from their embedded or linked contents (PSD/PSB, PNG, JPG) with their perspective, warps and smart filters (blurs, sharpen, unsharp mask, high pass, median, maximum, minimum, offset, mosaic, invert, solarize, curves, brightness/contrast and more).
- **Full compositing**: all 27 blend modes, groups (pass-through and knockout), clipping masks, layer masks, vector masks, fill layers (solid, gradient, pattern), shape strokes, opacity and fill opacity, Blend If and channel restrictions.
- **Replace text** in any text layer, including layers inside smart objects, before rendering. The layer keeps its font, size, color, effects and warp.
- **Template variants**: one PSD in, many images out. Give a list of variants (or a CSV with one row per image), each with its own texts and visible layers.
- **Edited PSD output** (optional): get the PSD/PSB back with the new text, still editable in Photoshop, next to the image.
- **Show or hide layers by name** before rendering, with wildcards and group paths (`Draft*`, `Header/Logo`, `#12`). Remove watermarks or guides, switch template options on and off, or hide every text layer for a clean background.
- **Many files at once**: upload files, paste links (direct, Google Drive, Dropbox, OneDrive/SharePoint, GitHub), pick a key-value store, or send ZIP archives full of PSDs. All images (and edited PSDs) also come in a single ZIP.
- **Output the way you need it**: PNG, JPEG, WebP, AVIF or TIFF; quality and PNG compression; scale by percent or fit inside a max width/height; background color for transparent areas; trim empty edges; thumbnails; file name prefix.
- **Text content and layer data** for every file: the text of each text layer, plus the full layer list (name, group path, type, visibility, opacity, fill opacity, clipping, blend mode, position, size).
- **Text masks** (optional): one grayscale PNG per text layer showing exactly where its letters land, for translation, inpainting and QA workflows.
- **Never charges for failures**: a broken link, a file that isn't a PSD or a file over your size limit is reported with a clear reason and costs nothing.

### Who uses it

- **Marketing and e-commerce teams** rendering banners, social posts and product images from PSD templates, in every language and size.
- **Comic, manga and webtoon translators** putting the translation straight into the text layers, rendering the pages and keeping an editable PSD, plus clean text-free backgrounds and text masks.
- **Personalization at scale**: certificates, badges, tickets, name cards, price tags and social cards from one template and a spreadsheet.
- **Print-on-demand and template shops** generating previews and thumbnails for thousands of PSD listings.
- **Developers and automation builders** (Make, Zapier, n8n, your own backend) who need a PSD to image API with no Photoshop license and no desktop step.
- **Agencies and archivists** batch-converting old PSD/PSB libraries into web-friendly formats.

### Quickstart

1. Open the **Input** tab.
2. Add your files under **📂 Photoshop files**: drop them in *Upload PSD / PSB files*, paste links in *PSD / PSB links*, or both. ZIP archives work.
3. Optional: add your fonts under **🔤 Fonts** (upload files or a ZIP of your font folder).
4. Choose the **Output format** and any extras, then click **Start**.
5. Open the **Output** tab: each row has an image preview and a download link. The *ZIP with all images* link downloads everything at once.

The prefilled example converts one sample banner so you can see the result in a few seconds.

### Edit text and fill templates

**Same change in every file.** Use **Replace text** (key = layer, value = new text):

| Key (layer) | Value (new text) |
|---|---|
| `Headline` | `SUMMER SALE` |
| `Card/Name` | `Ana Pérez` (layer *Name* inside group *Card*) |
| `Price*` | `$19.99` (every text layer whose name starts with *Price*) |
| `Logo box/Title` | `ACME` (text layer *Title* inside smart object *Logo box*) |

Write `\n` for a new paragraph. Layers are matched by name (case-insensitive, `*` and `?` wildcards), by group path or by index (`#12`); the `texts` field of any result lists the exact layer names. The new text keeps the layer's font, size, color, effects and warp.

**Many images from one PSD.** Use **Variants** (JSON) or **Variants from a CSV / JSON file**. Every variant becomes one image named `<file>-<variant>`:

```json
[
  { "name": "es", "texts": { "Headline": "REBAJAS", "Subheadline": "Hasta 40% en todo" }, "hide": ["Sun"] },
  { "name": "pt", "texts": { "Headline": "PROMOÇÃO" }, "show": ["Draft note"] }
]
```

The same thing as a CSV (columns named after text layers; `name`, `file`, `show` and `hide` are optional, empty cells keep the original text):

```csv
name,Headline,Subheadline,hide,show
es,REBAJAS,Hasta 40% en todo,Sun,
pt,PROMOÇÃO,,,Draft note
```

![Two variants rendered from the same PSD](https://scrapers.lat/samples/template-variants-example.jpg)

*Both images come from the sample PSD in one run: new texts, a different font forced with the font map (Bebas Neue drawn as Anton), and different layers switched on and off.*

Use the `file` column (or `"files": ["banner*.psd"]`) to send a row to specific PSDs when you convert several templates at once. Turn on **Also save the edited PSD** to get each variant back as an editable PSD as well.

### Fonts: how text is matched

Photoshop files store the **names** of their fonts, not the fonts themselves. For each font used in a text layer, the converter looks in this order:

1. **Your fonts** (uploads, links, ZIPs or the selected key-value store). TTF, OTF, TTC, WOFF and WOFF2 are accepted. Your fonts always win.
2. **Google Fonts** (1,900+ families), downloaded automatically in the exact weight and style. You can also preload families by name.
3. **Replacements for commercial fonts** that aren't free to distribute:
   - *metric-compatible* (same letter widths, so lines break exactly like the original): Arial, Helvetica, Times New Roman, Courier New, Calibri, Cambria, Georgia;
   - *look-alikes*: Gotham and Proxima Nova, Futura, Avenir, Myriad, Minion, Garamond, Segoe UI, SF Pro, Impact, Gill Sans, DIN, Trebuchet, comic lettering fonts and more;
   - *script-matched*: Japanese, Chinese and Korean system fonts (Kozuka, Hiragino, Meiryo, MS Gothic/Mincho, SimHei, SimSun, PingFang, Malgun, Gulim…) use Noto fonts of the same script and style.
4. **Closest style of the same family**, then of a common sans, serif or monospace family, with synthetic bold or italic when needed.
5. **The built-in font library** (Noto including Chinese/Japanese/Korean, DejaVu, Liberation, Roboto, Open Sans, Inter and more), which also covers any character your fonts lack.

Want a specific replacement? Use the **Font map** (key = font in the PSD, value = font to draw it with, e.g. `CCWildWords-Roman` → `Anton-Regular`). The target can be one of your fonts, a built-in font or any Google Fonts family, which is downloaded automatically.

Every result says what happened in `fontsResolved` (requested font, family used, source, match type) and lists anything still unavailable in `fontsMissing`, so you know exactly which fonts to upload for a pixel-exact match.

![Commercial fonts replaced automatically](https://scrapers.lat/samples/font-substitution-example.png)

*A test file using ArialMT, Helvetica-Bold, Gotham-Black, CC Wild Words, an unknown brand font and Kozuka Gothic. Nothing was uploaded.*

### Input reference

| Field | Type | Description |
|---|---|---|
| `psdFiles` | file upload (array) | PSD/PSB files or ZIP archives you upload. |
| `psdUrls` | array of links | Public links to PSD/PSB files or ZIPs. Google Drive, Dropbox, OneDrive/SharePoint and GitHub share links are converted to downloads automatically. |
| `fileStore` | key-value store | Optional. Use every PSD/PSB, ZIP and font stored in one of your key-value stores. |
| `linkedFiles` | file upload (array) | Outside files of linked smart objects (PSD, PSB, PNG, JPG or a ZIP), matched by file name. Files inside a ZIP of PSDs are found automatically. |
| `linkedFileUrls` | array of links | Links to those files. |
| `fontFiles` | file upload (array) | Font files or ZIPs of fonts. |
| `fontUrls` | array of links | Links to font files or font ZIPs. |
| `googleFonts` | array of names | Google Fonts families to preload, e.g. `Poppins`, `Bebas Neue`. |
| `fontMap` | key-value list | Draw font *key* (name in the PSD) with font *value*. |
| `autoDownloadGoogleFonts` | boolean | Find missing fonts on Google Fonts automatically. Default `true`. |
| `fontSubstitution` | `lookalike` / `metric` / `off` | Replacement policy for commercial fonts. Default `lookalike`. |
| `useBuiltInFonts` | boolean | Use the built-in font library. Default `true`. |
| `textReplacements` | key-value list | Replace the text of matching text layers in every file. Key: layer name, wildcard, group path, `#index` or `Smart object/Layer`. Value: new text (`\n` = new paragraph). |
| `variants` | array of objects | One image per variant: `name`, `texts` (layer → text), `show`, `hide`, `files` (PSD name filter). |
| `variantsFile` | file upload or link | CSV or JSON with one variant per row (columns = text layers, plus optional `name`, `file`, `show`, `hide`). |
| `textRendering` | `rerender` / `original` | Redraw text with fonts, or keep the pixels Photoshop saved. Default `rerender`. |
| `hideLayers` | array | Layers/groups to hide. Case-insensitive, `*` and `?` wildcards, group paths (`Header/Logo`) or index (`#12`). |
| `showLayers` | array | Layers/groups to switch on (their parent groups are switched on too). |
| `hideTextLayers` | boolean | Render without any text. Default `false`. |
| `exportTextMasks` | boolean | Save one coverage mask per text layer. Default `false`. |
| `renderSmartObjects` | boolean | Re-render smart objects from their contents instead of the saved preview. Default `false` (smart objects with replaced text are always re-rendered). |
| `outputFormat` | `png` / `jpeg` / `webp` / `avif` / `tiff` | Output format. Default `png`. |
| `quality` | 1-100 | Quality for JPEG, WebP, AVIF, TIFF. Default `90`. |
| `pngCompression` | 0-9 | PNG compression level (lossless). Default `6`. |
| `backgroundColor` | text | Fill transparent areas, e.g. `#FFFFFF`. Empty keeps transparency. |
| `scalePercent` | 1-400 | Resize relative to the canvas. Default `100`. |
| `maxWidth` / `maxHeight` | pixels | Fit inside these bounds (never enlarges). `0` = no limit. |
| `trimTransparentEdges` | boolean | Crop empty borders. Default `false`. |
| `thumbnailWidth` | pixels | Also create a thumbnail. `0` = none. |
| `fileNamePrefix` | text | Prefix for every output file name. |
| `createZip` | boolean | One ZIP with every image when more than one file is converted. Default `true`. |
| `includeLayerDetails` | boolean | Add the full layer list to each result. Default `true`. |
| `saveEditedPsd` | boolean | Also save the PSD/PSB with the replaced text, still editable. Free. Default `false`. |
| `maxConversions` | integer | Cap on images produced (and charged) per run, variants included. Default `1000`. |
| `maxFileSizeMb` | integer | Skip files above this size. Default `2048`. |
| `renderTimeoutSecs` | integer | Time limit per file. Default `300`. |

Example input:

```json
{
  "psdUrls": [
    "https://scrapers.lat/samples/summer-sale-banner.psd",
    "https://www.dropbox.com/scl/fi/your-file/templates.zip?rlkey=xxx&dl=0"
  ],
  "googleFonts": ["Poppins"],
  "textReplacements": [{ "key": "CTA", "value": "SHOP NOW" }],
  "fontMap": [{ "key": "CCWildWords-Roman", "value": "Anton-Regular" }],
  "hideLayers": ["Watermark", "Draft*"],
  "saveEditedPsd": true,
  "outputFormat": "webp",
  "quality": 85,
  "maxWidth": 1600,
  "thumbnailWidth": 400
}
```

### Output reference

One dataset row per file. Images are saved in the run's key-value store and linked from each row; the run's `OUTPUT` record has totals, the ZIP link and every font found during the run.

| Field | Description |
|---|---|
| `fileName`, `source` | The PSD (with its folder when it came from a ZIP) and where it came from. |
| `variant` | Variant name, when variants were used. |
| `status`, `error` | `converted` or `failed`, with the reason for failures (never charged). |
| `imageUrl`, `imageKey` | Download link and storage key of the rendered image. |
| `format`, `imageWidth`, `imageHeight`, `imageSizeBytes` | Output image details. |
| `thumbnailUrl` | Thumbnail link (when requested). |
| `psdUrl`, `psdKey` | Edited PSD/PSB link and key (when requested and text was replaced). |
| `psdWidth`, `psdHeight`, `colorMode`, `bitDepth`, `hasTransparency` | Document details. |
| `layerCount`, `groupCount`, `textLayerCount`, `smartObjectCount`, `adjustmentLayerCount` | Layer statistics. |
| `texts` | Text of every text layer (after replacements), with layer name, group path and visibility. |
| `textEdits` | Each text replacement and how many layers it changed. |
| `layersHiddenByRules`, `layersShownByRules` | How many layers your rules changed. |
| `fontsResolved`, `fontsMissing` | Fonts found automatically and fonts still unavailable. |
| `textMasks` | Per-text-layer masks: layer, link and position (when requested). |
| `layers` | Full layer list: index, name, path, type (pixel, text, group, fill, adjustment, smartObject), visibility, opacity, fill opacity, clipping, blend mode, position, size, text. |
| `warnings` | Notes about features drawn approximately or skipped. |
| `renderTimeMs`, `convertedAt` | Timing and timestamp. |

The **Converted images** view shows a preview of every image; the **Text content** view lists the text of each file and the replacements applied.

### Example output record

A real result from a run on the sample PSD with two variants, text replacement, a font map and the edited PSD turned on (`texts`, `fontsResolved` and `layers` trimmed):

```json
{
  "fileName": "summer-sale-banner.psd",
  "variant": "es",
  "source": "https://scrapers.lat/samples/summer-sale-banner.psd",
  "status": "converted",
  "imageUrl": "https://api.apify.com/v2/key-value-stores/<your-store>/records/summer-sale-banner-es.png?signature=…",
  "imageKey": "summer-sale-banner-es.png",
  "format": "png",
  "imageWidth": 1200,
  "imageHeight": 630,
  "imageSizeBytes": 134458,
  "thumbnailUrl": "https://api.apify.com/v2/key-value-stores/<your-store>/records/summer-sale-banner-es-thumbnail.png?signature=…",
  "psdUrl": "https://api.apify.com/v2/key-value-stores/<your-store>/records/summer-sale-banner-es.psd?signature=…",
  "psdKey": "summer-sale-banner-es.psd",
  "psdWidth": 1200,
  "psdHeight": 630,
  "colorMode": "Rgb",
  "bitDepth": 8,
  "hasTransparency": false,
  "layerCount": 9,
  "groupCount": 2,
  "textLayerCount": 6,
  "smartObjectCount": 0,
  "adjustmentLayerCount": 0,
  "texts": [
    {
      "layer": "Headline",
      "path": "Copy/Headline",
      "visible": true,
      "text": "REBAJAS"
    },
    {
      "layer": "Subheadline",
      "path": "Copy/Subheadline",
      "visible": true,
      "text": "Hasta 40% en todo"
    }
  ],
  "textEdits": [
    {
      "layer": "CTA",
      "layersChanged": 1,
      "error": null
    },
    {
      "layer": "Headline",
      "layersChanged": 1,
      "error": null
    },
    {
      "layer": "Subheadline",
      "layersChanged": 1,
      "error": null
    }
  ],
  "layersHiddenByRules": 1,
  "layersShownByRules": 0,
  "fontsMissing": [],
  "fontsResolved": [
    {
      "requested": "Poppins-Medium",
      "usedFamily": "Poppins",
      "source": "Google Fonts",
      "kind": "exact family"
    },
    {
      "requested": "Poppins-Bold",
      "usedFamily": "Poppins",
      "source": "Google Fonts",
      "kind": "exact family"
    }
  ],
  "textMasks": [],
  "warnings": [],
  "renderTimeMs": 1240,
  "convertedAt": "2026-10-04T11:57:53.741Z",
  "layers": [
    {
      "index": 3,
      "name": "Headline",
      "path": "Copy/Headline",
      "type": "text",
      "visible": true,
      "opacity": 100,
      "fillOpacity": 100,
      "clipped": false,
      "blendMode": "Normal",
      "left": 0,
      "top": 0,
      "width": 0,
      "height": 0,
      "text": "REBAJAS"
    },
    {
      "index": 4,
      "name": "Subheadline",
      "path": "Copy/Subheadline",
      "type": "text",
      "visible": true,
      "opacity": 100,
      "fillOpacity": 100,
      "clipped": false,
      "blendMode": "Normal",
      "left": 0,
      "top": 0,
      "width": 0,
      "height": 0,
      "text": "Hasta 40% en todo"
    }
  ]
}
```

### Run via API

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~psd-to-png-converter/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"psdUrls":["https://scrapers.lat/samples/summer-sale-banner.psd"],"outputFormat":"png"}'
```

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('scrapers_lat/psd-to-png-converter').call({
    psdUrls: ['https://scrapers.lat/samples/summer-sale-banner.psd'],
    outputFormat: 'webp',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const it of items) console.log(it.fileName, it.status, it.imageUrl);
```

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("scrapers_lat/psd-to-png-converter").call(run_input={
    "psdUrls": ["https://scrapers.lat/samples/summer-sale-banner.psd"],
    "outputFormat": "jpeg",
    "backgroundColor": "#FFFFFF",
})
for it in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(it["fileName"], it["status"], it["imageUrl"])
```

### Pricing and limits

- **$0.05 per image produced** ($50 per 1,000 conversions), with lower prices on higher Apify plans. One PSD/PSB in = one conversion, whatever the output format; with variants, every variant image counts as one conversion.
- Edited PSDs, thumbnails, text masks, layer details, text content and the ZIP download are **included at no extra cost**.
- Failed files are **never charged**.
- Your run's **spending limit is respected**: the run stops converting before it would go over, and you are only charged for images you receive.
- Free Apify plans can convert up to 10 files per run.
- Big files: the default 2 GB memory handles typical PSDs. For large PSB files (hundreds of MB, huge canvases) start the run with 4-8 GB of memory.

### FAQ and troubleshooting

**Do I need Photoshop or a license?**
No. Everything runs on Apify; you only need the PSD files.

**My text looks different from Photoshop.**
Almost always a font is missing or is a different version. Check `fontsMissing` and `fontsResolved` in the result, then upload the exact font files (or a ZIP of your font folder) and run again. Uploaded fonts always take priority.

**I edited the text with a script or another app and the old text still shows elsewhere.**
That is the problem this converter solves: with *Redraw text with fonts* (the default) every text layer is laid out again from its current text, so the image always shows what is in the file.

**Can I get the image exactly as Photoshop last saved it?**
Yes, set **Text layers** to *Keep original pixels*. Fonts are then not needed for text.

**What do replaced texts look like?**
Each new paragraph keeps the paragraph settings of the old paragraph in the same position and the character style used most in it. A word highlighted in another color or weight in the original is therefore drawn in the main style; to keep mixed styles, split them into separate text layers in the template.

**My smart object is linked to an outside file.**
Upload the linked files under **Linked smart object files** (or keep them in the same ZIP as the PSD) and turn on **Re-render smart objects**. Without them the preview saved in the PSD is used, which is usually what Photoshop showed.

**Which features are approximated?**
Very little. Photoshop's random patterns (the Dissolve blend mode and noise gradients) are drawn with the same density but different dots, and a smooth ramp is used for noise gradients. Extreme stacks of color adjustments with out-of-gamut colors can land a few levels away from Photoshop. Noise, distort and Camera Raw smart filters and smart filter masks are not applied (the saved preview is used instead), and duotone files that use color-book inks without a saved preview are shown in grayscale. Edited PSDs cannot be written for bitmap and multichannel documents (the image is still produced). Every case is listed in the row's `warnings`, never a crash.

**My Google Drive / Dropbox link fails.**
Make sure the file is shared as "anyone with the link". Private files can be uploaded instead, or stored in an Apify key-value store and selected under *…or a key-value store with your files*.

**How do I export several versions of the same template?**
Use **Variants**: each one sets its own texts and visible layers, and all images come out of a single run. For hundreds of versions, upload a CSV with one row per image.

**Is my data private?**
Your files and images stay in your own Apify storage, under your account's data retention settings.

Need a feature, a format or a custom workflow? Open an issue on the **Issues** tab, we answer fast.

# Actor input Schema

## `psdFiles` (type: `array`):

Drop one or more Photoshop documents (.psd or .psb). ZIP archives full of PSDs work too. Each file is one conversion.

## `psdUrls` (type: `array`):

Public links to .psd / .psb files or ZIP archives, one per line. Direct links work, and so do Google Drive, Dropbox, OneDrive/SharePoint and GitHub share links.

## `fileStore` (type: `string`):

Optional. Pick one of your Apify key-value stores: every PSD/PSB, ZIP and font file stored in it is used (PSDs are converted, fonts are loaded). Handy for big batches you upload once and convert many times.

## `linkedFiles` (type: `array`):

Only needed for smart objects that are linked to outside files (Place Linked in Photoshop). Upload those files (PSD, PSB, PNG, JPG) or a ZIP of the folder; they are matched by file name. Files inside a ZIP you uploaded as a PSD are found automatically.

## `linkedFileUrls` (type: `array`):

Links to the outside files of linked smart objects (or a ZIP of them).

## `fontFiles` (type: `array`):

Your own font files (.ttf, .otf, .ttc, .woff, .woff2) or a ZIP with a whole font folder. Uploaded fonts always win over any other source, so the output matches your design exactly.

## `fontUrls` (type: `array`):

Links to font files or ZIP archives of fonts, one per line (direct, Google Drive, Dropbox or GitHub links).

## `googleFonts` (type: `array`):

Optional. Google Fonts family names to load in every weight and style, e.g. "Poppins", "Bebas Neue", "Noto Sans JP". Usually not needed: missing Google fonts are found automatically.

## `fontMap` (type: `array`):

Force a replacement font. Key: the font name stored in the PSD (as shown in "fontsMissing" or "fontsResolved", e.g. CCWildWords-Roman). Value: the font to draw it with: one of your uploaded fonts, a built-in font or a Google Fonts family (e.g. Anton-Regular or Anton).

## `autoDownloadGoogleFonts` (type: `boolean`):

When a text layer uses a font you didn't provide and it exists on Google Fonts (1,900+ families), download the right weight and style automatically and redraw the text with it.

## `fontSubstitution` (type: `string`):

What to use when a font is neither provided nor on Google Fonts. "Look-alike" uses metric-compatible fonts where possible (Arial, Helvetica, Times New Roman, Courier, Calibri, Cambria, Georgia keep the same letter widths and line breaks) and close free look-alikes for others (Gotham, Proxima Nova, Futura, Avenir, Myriad, Segoe, SF Pro, comic lettering fonts…). "Metric-compatible only" skips the look-alikes. "Off" uses a generic fallback face.

## `useBuiltInFonts` (type: `boolean`):

Include the built-in free fonts (Noto incl. Chinese/Japanese/Korean, DejaVu, Liberation, Roboto, Open Sans, Inter, Carlito, Arimo, Tinos, Cousine) for matching and for characters your fonts don't cover. Turn off for strictly your-fonts-only output.

## `textReplacements` (type: `array`):

Key: the text layer to change, by name (case-insensitive, \* and ? wildcards), group path (Card/Name), index (#12) or Smart object/Layer for text inside a smart object. Value: the new text; use \n for a new paragraph. Font, size, color and effects of the layer are kept.

## `variants` (type: `array`):

Produce one image per variant from the same PSD, e.g. one per language, product or person. Each variant is an object: {"name": "es", "texts": {"Headline": "Hola"}, "show": \["Badge"], "hide": \["Draft\*"], "files": \["banner\*.psd"]}. Every key is optional: "name" is added to the output file name, "files" limits the variant to matching PSD names. Each variant image counts as one conversion.

## `variantsFile` (type: `string`):

A CSV (or JSON array) with one row per image. Columns named after text layers set their text; optional columns: name, file (PSD name filter), show, hide (several layers separated by | or ;). Empty cells keep the original text. A public link to the file works too.

## `textRendering` (type: `string`):

"Redraw" lays every text layer out again from its text, so edited or translated text that was never re-saved in Photoshop shows correctly. "Original pixels" keeps the text exactly as Photoshop last saved it (fonts not needed).

## `hideLayers` (type: `array`):

Layer or group names to hide before rendering, one per line. Case-insensitive; \* and ? wildcards work; match a nested layer with its path ("Header/Logo") or by index ("#12"). Example: "Watermark", "Draft\*", "Guides/\*".

## `showLayers` (type: `array`):

Layer or group names to switch ON even if they are hidden in the file (their parent groups are switched on too). Same matching rules as "Hide layers". Great for exporting variants of a template.

## `hideTextLayers` (type: `boolean`):

Render the artwork without any text, e.g. clean backgrounds for comic/manga translation or template previews.

## `exportTextMasks` (type: `boolean`):

Also save one grayscale PNG per text layer showing exactly where its letters land on the canvas (handy for translation, inpainting and QA). Free extra.

## `renderSmartObjects` (type: `boolean`):

Draw smart objects again from their embedded or linked contents (with perspective, warps and supported smart filters) instead of the preview saved in the file. Smart objects whose text you replace are always re-rendered.

## `outputFormat` (type: `string`):

Image format of the result. PNG keeps transparency and is lossless; JPEG is smallest for photos; WebP and AVIF are modern web formats with transparency.

## `quality` (type: `integer`):

1-100. Higher = better looking and larger files. Ignored for PNG.

## `pngCompression` (type: `integer`):

0 (fastest, biggest file) to 9 (smallest file, slower). PNG is always lossless.

## `backgroundColor` (type: `string`):

Fill transparent areas with this color, e.g. "#FFFFFF" or "black". Leave empty to keep transparency (JPEG always gets white unless you set a color).

## `scalePercent` (type: `integer`):

Resize the result relative to the PSD canvas, e.g. 50 for half size or 200 for double. 100 = original size.

## `maxWidth` (type: `integer`):

Optional. Shrink the image to fit this width (keeps proportions, never enlarges). 0 = no limit.

## `maxHeight` (type: `integer`):

Optional. Shrink the image to fit this height (keeps proportions, never enlarges). 0 = no limit.

## `trimTransparentEdges` (type: `boolean`):

Crop away transparent (or uniform) borders around the artwork. Useful for stickers, logos and product cut-outs.

## `thumbnailWidth` (type: `integer`):

Also create a small preview image of this width (same format). 0 = no thumbnail. Free extra.

## `fileNamePrefix` (type: `string`):

Optional text added in front of every output file name, e.g. "es-" gives es-banner.png.

## `createZip` (type: `boolean`):

When more than one file is converted, also provide a single ZIP download with every image.

## `includeLayerDetails` (type: `boolean`):

Add the full layer list of each PSD to the results: name, group path, type, visibility, opacity, blend mode, position, size and text content.

## `saveEditedPsd` (type: `boolean`):

When text was replaced, also save an editable PSD/PSB with the new text (layers stay editable in Photoshop). Free of charge. Visibility rules (show/hide) only apply to the images.

## `maxConversions` (type: `integer`):

Safety cap on how many PSD files this run converts (and charges). Free Apify plans are limited to 10 per run.

## `maxFileSizeMb` (type: `integer`):

Files bigger than this are skipped (not charged). Large PSB files need more run memory: use 4096 MB or more for files above ~500 MB.

## `renderTimeoutSecs` (type: `integer`):

Stop working on a single file after this long and move on (not charged).

## Actor input object example

```json
{
  "psdUrls": [
    "https://scrapers.lat/samples/summer-sale-banner.psd"
  ],
  "googleFonts": [
    "Poppins",
    "Bebas Neue"
  ],
  "autoDownloadGoogleFonts": true,
  "fontSubstitution": "lookalike",
  "useBuiltInFonts": true,
  "textRendering": "rerender",
  "hideLayers": [
    "Watermark",
    "Draft*"
  ],
  "hideTextLayers": false,
  "exportTextMasks": false,
  "renderSmartObjects": false,
  "outputFormat": "png",
  "quality": 90,
  "pngCompression": 6,
  "scalePercent": 100,
  "maxWidth": 0,
  "maxHeight": 0,
  "trimTransparentEdges": false,
  "thumbnailWidth": 0,
  "createZip": true,
  "includeLayerDetails": true,
  "saveEditedPsd": false,
  "maxConversions": 1000,
  "maxFileSizeMb": 2048,
  "renderTimeoutSecs": 300
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `files` (type: `string`):

No description

## `zip` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "psdUrls": [
        "https://scrapers.lat/samples/summer-sale-banner.psd"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/psd-to-png-converter").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "psdUrls": ["https://scrapers.lat/samples/summer-sale-banner.psd"] }

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/psd-to-png-converter").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "psdUrls": [
    "https://scrapers.lat/samples/summer-sale-banner.psd"
  ]
}' |
apify call scrapers_lat/psd-to-png-converter --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapers_lat/psd-to-png-converter"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/txFkCYClJco4wOSw5/builds/h9bGVZD6QBkqNgcsg/openapi.json
