Film assistant

Beta

Clean up an image in Photoshop

Clean up a generated location image in Photoshop: remove what does not belong, repair smeared signs and warped textures, and match the light, with every fix on its own layer.

Runs in Photoshop on your computer

Best for
Generated location stills and backgrounds that need to hold up on a big screen.
Runs in
Photoshop 25.0 or later
Time
15 to 30 min
Cost
The work in Photoshop is free. NOLGIA generation inside it is priced as usual.

Already have an account? Sign in

Create a free account and NOLGIA Agent opens with this preset. It works in Photoshop through the NOLGIA plugin.

Start it from your agent

Paste this into Claude Code, Claude Desktop, Cursor or any agent with NOLGIA connected, with Photoshop open. The agent follows NOLGIA's workflow for this preset step by step, and asks before it changes anything big.

Starter prompt

Use NOLGIA to clean up my generated location image in Photoshop: remove what does not belong, repair smeared signs and broken textures, and match the light, keeping every fix on its own editable layer.

In Claude Code it is also a command: /mcp__nolgia__photoshop-image-fixer. Open in Claude needs NOLGIA added to Claude as a connector.

What it does

The NOLGIA assistant makes a generated location image hold up on screen without changing its composition. It reads the image, lists what does not belong and what looks generated, like stray objects, garbled signs or warped bricks, and lets you pick what to fix. Small removals use Photoshop's own Content-Aware Fill. Larger repairs, like repainting a sign so it reads properly, use a NOLGIA masked edit that changes only the areas you picked.

Every fix is its own named layer with a mask, inside one NOLGIA Cleanup group, matched to the light and grain around it, so you can adjust it or switch it off. Your original pixels are never touched, and a safety copy of the document is saved first. You get the finished image in your NOLGIA library, with before and after previews.

You need Photoshop 2024 or later and NOLGIA for Photoshop. The work in Photoshop is free. NOLGIA edits are priced as usual, and the assistant gives you the total for its plan before anything is generated.

Use cases

  • Fixing garbled signs and lettering in a generated street scene
  • Removing stray objects from a location still
  • Getting a generated background ready for a composite

The workflow

The written steps your agent follows in Photoshop, the same for every agent: the rules every Photoshop workflow keeps (a safety copy first, everything stays editable, a preview after each change), then this preset's own steps.

Read the workflow

Rules for every Photoshop workflow

These instructions are served to the agent with every Photoshop preset in the Film assistant category. The agent works through the NOLGIA Bridge tools (nolgia_app_*) on Photoshop running on the person's own computer. Code for nolgia_app_run is UXP JavaScript (language: "uxp").

Before anything changes

  1. Call nolgia_app_status. If Photoshop is not listed, stop and tell the person in two lines: install NOLGIA for Photoshop from nolgia.ai/plugins/photoshop, then open the NOLGIA panel from Photoshop's Plugins menu and sign in. Do not guess or continue without it.
  2. Call nolgia_app_info. Read what is really open: the documents, the active one's size, resolution, colour mode and bit depth, its layers (groups, masks, what is hidden or locked), the selected layer and any selection. Describe it back in one sentence so the person can correct you. If the image to work on is in the NOLGIA library instead, bring it in with nolgia_app_import: it opens as a new document when none is open.
  3. If the document has a path, make a safety copy first: nolgia_app_export with format: "psd" saves <name>-copy.psd next to it and never overwrites a file. If it was never saved (an image imported from NOLGIA, a new document), ask where to keep the working PSD, offer a default next to the person's other project files, and save it there with a nolgia_app_run that calls doc.saveAs.psd(...) (see below), or ask the person to use File > Save As, and wait.
  4. Ask only the questions the workflow lists. Offer a sensible default for each so the person can just say "go".

While working

  • Change the document in small steps: one nolgia_app_run per logical step, each setting result to a short summary (layer names and ids, counts, bounds). Each run is one step in Photoshop's History, named "NOLGIA: run code", so the person can undo it in one go; a run that fails is undone for you.
  • Never delete, merge, flatten, rasterize or rename the person's own layers unless they asked. Work on copies and new layers, and put everything you add in a group named after the workflow (for example NOLGIA Cleanup).
  • Keep everything editable: retouching on its own layers with layer masks, placed images as Smart Objects, colour and light as adjustment layers. No destructive filters on the original pixels.
  • After each visible change, call nolgia_app_preview and look at the image before moving on. If it looks wrong, fix it before the next step. Do not describe a result you have not seen. The preview shows the whole active document; to look closely at one area, duplicate a crop of it into a temporary document in a run, preview that, then close it without saving.
  • If code fails, read error (it names the line of your code), fix it and try once more. After two failures on the same step, explain what failed in plain words and ask how to proceed.

Photoshop UXP that bites

  • Every run already runs inside core.executeAsModal, so edits work as they are. Do not wrap code in core.executeAsModal yourself: an error thrown inside it comes back as bare text with no line number. If you need a nested modal scope, use the modal(async (ctx) => ...) helper.
  • batchPlay does not throw when a step fails; it returns {_obj: "error", message} and carries on. Use the play([...]) helper, which throws on the first failed step. Check what a step did (for example read the layer back) before relying on it.
  • doc.layers.add() and doc.createLayer() put the new layer at the top of the stack, inside the top group when the top item is a group, whatever layer is selected. To put a layer where you mean, select the layer it should sit above with play([{ _obj: "select", _target: [{ _ref: "layer", _id: id }], makeVisible: false }]) and make it with play([{ _obj: "make", _target: [{ _ref: "layer" }], using: { _obj: "layer", name } }]), or move it afterwards with layer.move(target, constants.ElementPlacement.PLACEBEFORE) (above) or PLACEAFTER (below); PLACEINSIDE puts it in a group.
  • doc.createLayerGroup({ name }) always makes the group at the top of the stack. To nest groups, move them in with group.move(parent, constants.ElementPlacement.PLACEINSIDE), which puts the moved layer at the top of the parent: move them bottom one first.
  • Deleting a layer leaves no layer selected; select one before the next step. nolgia_app_import places the image right above the selected layer (inside its group), or at the top of the stack when none is selected. With a group itself selected it lands above the group, not in it: move it in afterwards.
  • Photoshop hands out a new object each time you read a layer, so compare layers by id, never with ===, and keep ids (not objects) between runs. The same goes for documents: keep the document's id and find it with app.documents.find((d) => d.id === id), because opening, duplicating or importing changes app.activeDocument.
  • Fill, Content-Aware Fill, filters and adjustments act on the selected layer, inside the selection when there is one. Content-Aware Fill needs pixels on that layer (it does nothing on an empty layer): duplicate the source layer, fill inside the selection on the copy, then give the copy a mask of just the patch.
  • In descriptors, RGBColor takes red, grain (green) and blue, 0 to 255.
  • A layer's bounds are what its mask lets through. A layer whose mask hides everything reports zero bounds.
  • Placing an image clears the selection (nolgia_app_import puts it back). Keep a selection you need across steps in a channel, or rebuild it.
  • Code runs on Photoshop's one JavaScript thread. A loop that never awaits freezes Photoshop and nothing can stop it. timeout_seconds only stops NOLGIA waiting; keep each run short.
  • While a dialog is open in Photoshop (a save prompt, a filter's settings, the Graphics Processor notice at startup) Photoshop is busy: changes fail, and run says so and runs your code outside the modal scope, where it can only read. Ask the person to close the dialog, then run the step again.
  • await app.documents.add(...) makes the document and makes it active, but what it returns is not reliable: null, or even the document that was active before. Use app.activeDocument right after it (check its name).
  • doc.path is empty until the document is saved. Save with doc.save() or doc.saveAs.psd(entry, options, asCopy); nolgia_app_run has fs (the UXP local file system, full access) to get entries: await fs.getEntryWithUrl("file:/C:/Projects/shot.psd") for an existing file, await (await fs.getEntryWithUrl("file:/C:/Projects")).createFile("shot.psd", { overwrite: true }) for a new one.

Recipes that work (Photoshop 2026)

  • Select a layer: play([{ _obj: "select", _target: [{ _ref: "layer", _id: id }], makeVisible: false }]).
  • Copy the original into a group: await original.duplicate(group, constants.ElementPlacement.PLACEINSIDE, "Remove: cone").
  • Selections: doc.selection.selectRectangle({ left, top, right, bottom }), selectEllipse(...), selectPolygon([{ x, y }, ...]); pass constants.SelectionType.EXTEND as the second argument to add to it. Grow it with play([{ _obj: "expand", by: { _unit: "pixelsUnit", _value: 5 }, selectionModifyEffectAtCanvasBounds: false }]) and soften it with the same step as { _obj: "feather", radius: { _unit: "pixelsUnit", _value: 2 }, ... }.
  • Content-Aware Fill inside the selection, on the selected layer: play([{ _obj: "fill", using: { _enum: "fillContents", _value: "contentAware" }, contentAwareColorAdaptationFill: true, opacity: { _unit: "percentUnit", _value: 100 }, mode: { _enum: "blendMode", _value: "normal" } }]). The same fill with _value: "black", "gray" (50% gray) or "color" plus color: { _obj: "RGBColor", red, grain, blue } fills plainly; play([{ _obj: "delete" }]) clears the selection on a normal layer.
  • Mask the selected layer to the selection: play([{ _obj: "make", new: { _class: "channel" }, at: { _ref: "channel", _enum: "channel", _value: "mask" }, using: { _enum: "userMaskEnabled", _value: "revealSelection" } }]); remove a mask with play([{ _obj: "delete", _target: [{ _ref: "channel", _enum: "channel", _value: "mask" }] }]).
  • An adjustment layer, right above the selected layer: play([{ _obj: "make", _target: [{ _ref: "adjustmentLayer" }], using: { _obj: "adjustmentLayer", name, type } }]) with type such as { _obj: "curves", presetKind: { _enum: "presetKindType", _value: "presetKindCustom" }, adjustment: [{ _obj: "curvesAdjustment", channel: { _ref: "channel", _enum: "channel", _value: "composite" }, curve: [{ _obj: "paint", horizontal: 0, vertical: 0 }, { _obj: "paint", horizontal: 128, vertical: 121 }, { _obj: "paint", horizontal: 255, vertical: 255 }] }] } or { _obj: "photoFilter", color: { _obj: "RGBColor", red: 236, grain: 138, blue: 0 }, density: 18, preserveLuminosity: true } (warming). Made while a selection is active, it takes the selection as its mask. Clip it to the layer below with play([{ _obj: "groupEvent", _target: [{ _ref: "layer", _enum: "ordinal", _value: "targetEnum" }] }]).
  • Noise on the selected layer: play([{ _obj: "addNoise", distort: { _enum: "distort", _value: "gaussianDistribution" }, noise: { _unit: "percentUnit", _value: 4 }, monochromatic: true }]).
  • Blend mode and opacity: layer.blendMode = constants.BlendMode.OVERLAY, layer.opacity = 55.

Using NOLGIA where it helps

  • Photoshop's own tools come first: Content-Aware Fill for small removals, healing on a copy layer, adjustment layers for light and colour. They are free and stay on the person's computer.
  • For a larger change (repainting part of the scene, a new sky, a surface that needs real detail) use a NOLGIA masked edit: export the document with nolgia_app_export (png), make a mask PNG the same size whose transparent pixels mark the area to repaint (a new document with a transparent background, filled black, with the area deleted; png export keeps the transparency), export that too, then call nolgia_image_to_image with the first as image_url (its signed URL from nolgia_get_asset) and the mask as mask_asset_id on a model that publishes image.inpaint_mask (gpt-image-2.5-flare or gpt-image-2.5-sunburst; check nolgia_list_models). The model redraws the whole picture (sharper and often a little brighter, at a larger size) but keeps it aligned. Bring the result in with nolgia_app_import: an image with the document's shape lines up with the canvas exactly. Mask it to just the repaired things so everything else stays the person's original pixels.
  • These generations cost credits: say what you are about to make and roughly what it costs (read it from nolgia_list_models or the tool's estimate) before you run it. Work in Photoshop itself is free.
  • Photoshop's Generative Fill uses the person's Adobe generative credits and has no scripting interface NOLGIA supports. If they prefer it, make the selection and the target layer ready, ask them to click Generative Fill and type the prompt you suggest, and continue once they say it is done.

Finishing

  1. Save the document with a nolgia_app_run that calls await doc.save(), never over a different file.
  2. Export a png or jpg with nolgia_app_export so the person has the result in their NOLGIA library, and show it.
  3. Tell the person, in a few lines: what you changed, where it lives in the document (group and layer names), how to switch a fix off (hide the layer or paint its mask), and the path of the safety copy.

Clean up an image in Photoshop

Refine a generated location image so it holds up on screen: stray objects gone, smeared signs and warped surfaces repaired, light and grain consistent, the composition unchanged. Every fix is its own layer with a mask inside one group, so the person can see, adjust or switch off each one, and the original pixels are never touched.

Ask

  1. Which image? (Default: the active document. If it is in the NOLGIA library, bring it in with nolgia_app_import.) Preview it and read it carefully first.
  2. What should go? Give a short numbered list of what you see that does not belong (stray objects, doubled or melted details, people or cars that break the shot) and let the person pick by number. (Default: everything on your list.)
  3. Which textures and surfaces need repair? List what looks generated: smeared or garbled signs, warped bricks or tiles, repeating patterns, melted edges. For each sign, ask what it should say, or whether it should be plain. (Default: signs become clean and plain, surfaces match their surroundings.)
  4. The light: keep it as it is, or a time of day, direction and mood (for example "late afternoon sun from the left, warmer"). How strong? (Default: keep the light, only match fixes to it.)
  5. Photoshop only (free), or NOLGIA edits where they do better (about 8 credits each with gpt-image-2.5-flare)? Give the total for your plan before anything is generated. (Default: Photoshop first, NOLGIA for the fixes Photoshop cannot do well, with the cost agreed first.)

Build

  1. Set up without touching the original. Make the safety copy (see the rules above) and save the working PSD. Keep the original layer as it is at the bottom (a background layer stays locked; that is fine). Make one group NOLGIA Cleanup above it for everything you add, with inner groups Remove, Repair and Light, in that order from the bottom (groups are made at the top level; move each into NOLGIA Cleanup, Remove first). Note the document id and the ids of the original layer and the groups: every later step finds them by id.
  2. Remove, one item per layer. For each item: duplicate the original layer into Remove as Remove: <item> and select the copy; select the item generously (a rectangle, ellipse or polygon a few pixels outside its edge, including its shadow), expand the selection 4 to 8 px, run Content-Aware Fill on the copy, feather the selection 2 px and give the copy a mask revealing only the selection. Preview a close crop. On open ground (cobbles, pavement, grass, sky) this is usually invisible. If the fill looks cloned or smeared (structure behind the object, such as a shopfront, doorway or railing), use a NOLGIA masked edit (step 3) for that item instead and say so.
  3. Repair with NOLGIA masked edits. For the signs and surfaces the person picked (and removals Photoshop cannot fill well), in one edit when they sit apart from each other (one edit, one price):
  4. Export the document as png with nolgia_app_export (after the removals, so the edit sees them done).
  5. Make the mask: app.documents.add({ width, height, resolution, mode: "RGBColorMode", fill: "transparent", name: "NOLGIA edit mask" }) with the document's size, then work on app.activeDocument (see the rules above); fill it black, and for each area select a rectangle a few pixels larger than the damage (the whole lettering of a sign, the whole object to remove with its shadow) and delete it. Export it as png (it is the active document now; the export keeps the transparency), then close it without saving.
  6. Call nolgia_image_to_image with the document's signed URL as image_url, the mask as mask_asset_id, gpt-image-2.5-flare, the document's aspect ratio, and a prompt that numbers each fix, says what should be there, and asks to keep everything else ("1) remove the white plastic chair in front of the bakery: show the wooden lower panel and the sunlit pavement behind it; 2) repaint the sign so it reads Boulangerie in crisp dark script, same size and slant; keep everything else exactly as it is"). Show the person the result before you place it.
  7. Import it with nolgia_app_import, move it into Repair, name it Repair: <what>, and give it a mask of the repaired things, feathered 2 to 3 px. Make that mask cover each whole thing you repaired, not only the area NOLGIA was asked to repaint: new lettering can run past it (a sign cut off at Boulangeri needs the whole sign board in the mask).
  8. Match each patch to the plate. Preview each patch close up next to its surroundings. When a patch is brighter, darker or a different colour, select it and add a Curves adjustment layer Match: <what> clipped to it, and nudge it until the edges disappear. NOLGIA edits tend to come back a little brighter and cleaner than the plate (in testing, about 7 levels out of 255): start by lowering the midtones that much, and keep the grain step below.
  9. Light. Only if the person asked for a change: add adjustment layers named for their job and move them into Light: a warming Photo Filter (density 15 to 25) for warmth over the whole frame (no selection), and for direction a gentle Curves lift made while a big selection is active: a rectangle that runs off the canvas on the sun side and ends about half way across, feathered 200 px, so the lift fades out away from the sun. Keep each adjustment gentle; stack them rather than pushing one.
  10. Grain. Add a layer Grain at the top of NOLGIA Cleanup: filled 50% gray, monochromatic Gaussian Add Noise about 3 to 5%, blend mode Overlay, opacity about 50% and then by eye, so the patches and the plate have the same texture in a 100% crop. Mask it to the patched areas if the plate already has strong grain elsewhere.

Check

  • Preview the whole frame, then a close crop of every fix. Look for cloned patterns, hard or haloed mask edges, patches brighter or smoother than their surroundings, signs that still read as garbled, lines that bend where they should be straight.
  • Hide NOLGIA Cleanup, preview (before), show it, preview (after), and compare: the composition, the camera and everything the person did not ask about must be the same.
  • nolgia_app_info: the original layer is unchanged, every fix is a named layer or Smart Object with a mask inside NOLGIA Cleanup, nothing is flattened or rasterized.

Deliver

Save the PSD, export a full-size png (and a jpg if they want a smaller file), and show the before and after previews side by side. Tell the person which layer holds each fix and how to adjust one (paint its mask white to show more, black to show less; hide a layer to switch the fix off), what NOLGIA generated and what it cost, and where the safety copy is.

Try it in Photoshop.

Install the free NOLGIA plugin for Photoshop, sign in, then ask your agent.

Get the Photoshop plugin