PhotoCraft v0.9.0

PhotoCraft is an open-source image editor designed as a clean-room reimplementation of Adobe Photoshop, built entirely in Rust. It provides a surprisingly broad set of professional image-editing features, including layers, masks, adjustment layers, filters, vector shapes, editable text, brushes, and native PSD support.

The project is particularly interesting for users who want a local, open-source Photoshop alternative without relying on Electron, cloud services, or proprietary software. However, PhotoCraft is still in early alpha, so it is better viewed as a promising alternative under active development than as a complete replacement for Photoshop.

Features

PhotoCraft offers a substantial collection of image-editing tools:

  • Layer groups, clipping masks, pixel and vector masks

  • Adjustment layers for Curves, Levels, Vibrance, Hue/Saturation, Black & White, Gradient Map, Selective Color and more

  • Layer styles including Drop Shadow, Inner Shadow, Glow, Bevel & Emboss, Stroke, and overlays

  • Brush, Pencil, Mixer Brush, Clone Stamp, Healing Brush and other painting tools

  • Marquee, Lasso, Magic Wand, Quick Selection, Object Selection and Select Subject

  • Editable point and paragraph text

  • Pen and vector shape tools

  • Smart objects and smart filters

  • Free Transform with scale, rotate, skew, distort and perspective

  • History and History Brush

  • Multiple blend modes, opacity, fill and layer controls

  • Color management with RGB, Grayscale, CMYK and Lab

  • 8, 16 and 32-bit-per-channel documents

  • PSD and PSB support

  • PNG, JPEG, TIFF, WebP, GIF, BMP, TGA, ICO, OpenEXR, HDR, AVIF and other formats

  • Export preview with quality, transparency, scale and estimated file size

  • Command palette and recorded actions

Its PSD support is one of its strongest features. The project tests its implementation against real-world PSD files and reports very high rendering compatibility across its test corpora. Unsupported data is designed to be preserved rather than simply discarded when documents are saved.

Another unusual feature is its automation architecture. PhotoCraft exposes its editing engine through the desktop interface, CLI, JSON control channel and MCP, making the application suitable for scripted workflows and AI-agent automation.

Download PhotoCraft v0.9.0 - Software Mirrors

PhotoCraft v0.9.0 for Windows

photocraft-0.9.0-windows-x86.msi | 64.13 MB

photocraft-0.9.0-windows-x86-portable.zip | 75.5 MB

photocraft-0.9.0-windows-x64.msi | 66.23 MB

photocraft-0.9.0-windows-x64-portable.zip | 79.32 MB

photocraft-0.9.0-windows-arm64.msi | 61.65 MB

photocraft-0.9.0-windows-arm64-portable.zip | 74.95 MB

PhotoCraft v0.9.0 for macOS

photocraft-cli-0.9.0-macos-universal.zip | 64.75 MB

photocraft-0.9.0-macos-universal.dmg | 86.2 MB

PhotoCraft v0.9.0 for Linux

photocraft-0.9.0-linux-x86_64.tar.gz | 77.76 MB

photocraft-0.9.0-linux-x86_64.rpm | 78.42 MB

photocraft-0.9.0-linux-x86_64.flatpak | 58.28 MB

photocraft-0.9.0-linux-x86_64.deb | 78.95 MB

photocraft-0.9.0-linux-x86_64.AppImage.zsync | 258.86 kB

photocraft-0.9.0-linux-x86_64.AppImage | 73.89 MB

photocraft-0.9.0-linux-riscv64.tar.gz | 75.62 MB

photocraft-0.9.0-linux-riscv64.rpm | 76.35 MB

photocraft-0.9.0-linux-riscv64.deb | 76.65 MB

photocraft-0.9.0-linux-aarch64.tar.gz | 73.65 MB

photocraft-0.9.0-linux-aarch64.rpm | 75.12 MB

photocraft-0.9.0-linux-aarch64.flatpak | 53.92 MB

photocraft-0.9.0-linux-aarch64.deb | 75.79 MB

photocraft-0.9.0-linux-aarch64.AppImage.zsync | 245.97 kB

photocraft-0.9.0-linux-aarch64.AppImage | 70.21 MB

PhotoCraft v0.9.0 for BSD

photocraft-0.9.0-freebsd-x86_64.tar.gz | 77.25 MB

Others Download related to PhotoCraft v0.9.0

photocraft-web-0.9.0.zip | 10.94 MB

PhotoCraft v0.9.0 Source Code

PhotoCraft v0.9.0 Source code (zip)

PhotoCraft v0.9.0 Source code (tar.gz)

PhotoCraft v0.9.0 Release Notes:

What's Changed

  • Use craft-print for system printing by @skylartaylor in #3872
  • Tests: allow-list language-invariant bit-depth labels, add missing tr/hu 'Enable animations' (#4359) by @vangel76 in #4362
  • feat(automation): allow Crop and Straighten Photos through automation (#1052) by @buivanvu94 in #3917
  • Pencil: no 8-bit dither on aliased strokes, one flat colour at partial opacity by @cloudalister in #3990
  • Preserve grayscale appearance in profileless exports by @jonathanwxh-cell in #3978
  • Save As: a saved .pcraft manifest reports the file it was saved under by @switch87 in #3571
  • Selection: lasso polygons scan only the edges that cross each row by @xsvm in #3959
  • Fix group transform bounds with active pixel selections by @jonathanwxh-cell in #3970
  • fix(color): validate RGB working profiles atomically by @zenjabba in #3924
  • Load and save Photoshop Actions (.atn) (#4356, #219) by @FabioLissi in #4434
  • feat(engine): recolor vector shape layer fill with Alt+Backspace and Cmd+Backspace by @Gotix-eg in #3925
  • fix(ui): default the Move tool Auto-Select target to Group by @mroxso in #4093
  • fix(gpu): preflight compositor uniform buffer limits by @zenjabba in #3931
  • Properties: a new adjustment or fill layer brings Properties to the front (#4028) by @marcoarnulfo in #4079
  • Actions panel: set folders, dialog toggle, Insert Stop (#219) by @FabioLissi in #4456
  • Delete with several layers selected deletes them, not the active layer's targeted mask (#4025) by @marcoarnulfo in #4078
  • Fix multi-layer Delete and Move drags on a locked Background by @vbasky in #4109
  • File Handling: wire Maximize PSD and PSB File Compatibility (#204) by @Erica4fr in #3955
  • View: Esc leaves full screen modes (part of #4116) by @FredApps in #4145
  • .atn: map the remaining frequent Photoshop events (#219) by @FabioLissi in #4465
  • Windows: keep full screen and maximized apart; never restore full screen by @aweussom in #4396
  • Make channel filter previews match the committed edit by @jonathanwxh-cell in #3979
  • .atn: Place, Open, Image Size in percent, Paint Bucket and Insert Conditional (#219) by @FabioLissi in #4470
  • Quantize the colour field when Only Web Colors is on. by @vbasky in #4138
  • fix(ui): cancel unfinished Polygonal Lasso when switching tools by @Ni-zav in #4021
  • fix(ui): reject rotation angles outside f32 range by @Ni-zav in #4044
  • fix(move): no trail when dragging a shape past the canvas edge (#3946) by @alonfaraj in #4069
  • Resolve every pattern name before a batch delete removes any of them. by @vbasky in #4132
  • Brush cursor: the tip's centre mark follows Show Crosshair in Brush Tip by @Furash in #4105
  • Brush Settings: toggle switch rows without losing smoothing settings by @augrclk in #4463
  • Color Table: keep the transparent index inside the palette (#4186) by @davidmann4 in #4187
  • Stylus: a light Windows pen tap is pressure 0, not a full-pressure click by @Furash in #4072
  • Filters on a type layer: ask to rasterize or convert to a Smart Object instead of greying out by @marcoarnulfo in #4333
  • i18n(hu): informal address in the rows added on merge by @Skaywalker in #4334
  • Italian: native-speaker review of the UI catalog by @lucAmbr0 in #4290
  • Color Picker: CMYK foreground fills a CMYK document with the picked inks (#4196) by @vangel76 in #4339
  • Codecs: open and save DPX frames (#1049) by @przemyslvw in #4104
  • Brush: CMYK foreground paints the picked inks into a CMYK document (#4344) by @vangel76 in #4347
  • Paint Bucket and Edit > Stroke: a CMYK foreground writes the picked inks (#4351) by @vangel76 in #4352
  • perf(raster): moved fills keep sharing one copy-on-write tile by @SckraT in #4414
  • perf(compose): stop sweeping the bounds cache on every call once it i… by @SckraT in #4415
  • perf(engine): move layers without a second document clone by @SckraT in #4422
  • perf(compose): read PHOTOCRAFT_FX_NOCACHE once by @SckraT in #4423
  • perf(engine): read selection coverage per row when mixing edits back by @SckraT in #4424
  • Layer Style: OK keeps an Inner Glow's Center source (#4152) by @davidmann4 in #4120
  • Layers panel: double-clicking an effect row opens that layer's Layer Style (#4157) by @davidmann4 in #4131
  • Keep Liquify undo and redo working while a numeric field is focused. by @vbasky in #4134
  • Draw the Free Transform rotate arrow instead of hiding the pointer. by @vbasky in #4139
  • Snap 1 px pencil clicks to the pixel the aliased tip paints. by @vbasky in #4140
  • Image Size and Canvas Size: no silent resize of large documents in physical units (#4162) by @davidmann4 in #4163
  • Exposure: the slider keeps fractional stops (#4164) by @davidmann4 in #4165
  • Shape tools: the click-to-open-dialog tolerance is the same on HiDPI displays (#4205) by @davidmann4 in #4207
  • Rotate View: the image follows the pointer in a flipped view (#4226) by @davidmann4 in #4227
  • Brush resize HUD: horizontal is size and vertical is hardness in a rotated view (#4228) by @davidmann4 in #4229
  • feat(codecs): support full X11 rgb.txt color names in XPM by @Ni-zav in #4263
  • feat(codecs): add XPM2 plain-text image import support by @Ni-zav in #4264
  • Docs: refresh gaps.md against main (#4412) by @vangel76 in #4413
  • Docs: refresh target-app-parity and file-format-parity against main (#4417) by @vangel76 in #4418
  • Clone Stamp and History Brush: releasing a stroke commits the live pixels by @xsvm in #4019
  • Stylus: a pen held still is not a press-and-hold right click by @Furash in #4106
  • Refresh Liquify's zoomed preview when a stroke is undone. by @vbasky in #4135
  • fix(selection): avoid panics when sampling incomplete region masks by @Ni-zav in #4045
  • Type: Space inserts a space while editing type by @Hevarh1 in #4224
  • fix(algo): reject oversized Magic Eraser masks without overflow by @Ni-zav in #4043
  • fix(selection): validate Magic Wand pixel buffers before indexing by @Ni-zav in #4046
  • feat(ui): the shaped brush cursor turns and flips with the view by @FinnNk in #4233
  • Affinity import: pie shapes with huge angles no longer hang the reader by @dotCooCoo in #4054
  • Affinity: rectangles keep per-corner radii and straight corners (#1606) by @callmeBalloch in #4055
  • feat(ui): spring-loaded tool letters (#2672) by @FinnNk in #4238
  • Quick Selection: cut window sizes in parallel, cancel the larger ones once one is kept (-37% on 24 MP strokes, identical masks) by @syncroot in #4062
  • PSD: a zero-length annotation entry no longer hangs the import (#4149) by @davidmann4 in #4117
  • Swatches: reject colour values beyond f32 range so presets survive a restart (#4150) by @davidmann4 in #4118
  • Compose: the effect cache follows Transparency Shapes Layer and Blend If (#4151) by @davidmann4 in #4119
  • Auto-Select: honour layer mask density when picking layers (#4153) by @davidmann4 in #4121
  • Find and Replace Text: backward Change/Find moves past the replaced text (#4154) by @davidmann4 in #4122
  • Liquify, Puppet Warp and Perspective Warp: refuse locked smart objects (#4155) by @davidmann4 in #4123
  • Count tool: Marker Size and Label Size fields take effect (#4156) by @davidmann4 in #4124
  • Layers panel: show the lock icon for every lock (#4158) by @davidmann4 in #4159
  • Automation: reject an invalid document index instead of using the active document (#4160) by @davidmann4 in #4161
  • Paint Bucket and Gradient: validate opacity like the Magic Eraser (#4167) by @davidmann4 in #4168
  • Video layers: edits keep the timeline work area (#4170) by @davidmann4 in #4171
  • Warp: move only the selected part of a linked mask (#4175) by @davidmann4 in #4176
  • Contours (.shc): keep long names valid and readable (#4177) by @davidmann4 in #4179
  • Global Light: reject angles beyond f32 range instead of storing NaN (#4181) by @davidmann4 in #4182
  • Tests: set the Move tool's Auto-Select target to Layer in the layout_perf clicks (#4056) by @FabioLissi in #4548
  • feat: resize Save for Web previews and custom palette editing for Gif export by @TheDankness in #4129
  • Tests: GPU startup marker tests wait while another test's child process holds the lock by @dotCooCoo in #4251
  • Control: a transport that gives up knows whether the command was dispatched (#3662) by @marcoarnulfo in #4256
  • Canvas: a tool drag past the edge auto-scrolls the view (#4183) by @jonathanwxh-cell in #4257
  • fix(linux): respect GNOME's default light appearance (#4216) by @Ni-zav in #4289
  • Brush Settings: Brush Tip Shape lines up with the other section names (#4282) by @dhiorns15 in #4294
  • Properties: the Studio-layout themes show it for every layer (#4246) by @dhiorns15 in #4299
  • Give numeric type controls translated accessible names by @grlessa in #4310
  • Free Transform: unlinking W and H frees the handles too (#4174) by @dhiorns15 in #4322
  • fix(ui): make clickable tab, checkbox, and radio labels non-selectable (#3972) by @Korg1ch in #4331
  • fix(ui): use a linear gradient ramp glyph for the Gradient tool icon (#4172) by @Korg1ch in #4335
  • fix(ui): add Brushes button at top of Brush Settings control list (#4265) by @Korg1ch in #4354
  • fix(ui): keep brush settings section lock icons permanently visible (#4278) by @Korg1ch in #4300
  • Layers: Fill and the Paint Bucket edit an adjustment layer's mask when its icon is targeted (#4298) by @dhiorns15 in #4308
  • Object Selection: hover preview of the object it would select (Object Finder) (#4087) by @FredApps in #4095
  • feat(ui): add GRD import option to gradient map preset picker by @xtellarvoid in #4337
  • Type: every text edit respects Lock All (#4188) by @davidmann4 in #4189
  • Color Sampler: keep the CMYK readout in range on 32-bit documents (#4191) by @davidmann4 in #4192
  • Layer Comps: the warning icon clears only its own comp (#4197) by @davidmann4 in #4198
  • fix(type): key font menu caches on the shared engine's fonts (flaky font menu tests) by @bommerts in #4200
  • Vector masks: validate feather like pixel masks (#4201) by @davidmann4 in #4202
  • Shapes: a rectangle with a negative size extends from its origin like the other shapes (#4203) by @davidmann4 in #4204
  • Cryptomatte: decode the .blue/.alpha rank of every channel set (#4208) by @davidmann4 in #4209
  • EXR: an unnamed part can be opened by the name the part list gives it (#4210) by @davidmann4 in #4211
  • Bitmap mode: validate the halftone screen angle (#4214) by @davidmann4 in #4215
  • Find Edges and Solarize: treat CMYK values as ink (#4222) by @davidmann4 in #4223
  • fix(compose): paint interior effects over the layer's blend mode (#3996) by @alonfaraj in #4231
  • feat(ui): add hamburger menu to the Brush Settings panel (#4272) by @Sir-Starch in #4358
  • Simplify the raster stale-block filter for clippy's nonminimal_bool by @persi-man in #4314
  • Save for Web and Export As remember their settings across restarts (FILE-215-18) by @reynold-hu in #4184
  • fix(layer-picker): include text bounds in right-click layer selection (#4259) by @Ni-zav in #4288
  • Gradients: Photoshop's interpolation method for Gradient Overlay, gradient Stroke and the Gradient tool by @MrCloudy2 in #4292
  • fix(type): the Type tool's canvas pick skips text in hidden groups (#4320) by @FredApps in #4332
  • Smart Objects Warp: mesh knots span the contents on a skewed placement (#4113) by @vangel76 in #4341
  • Type: faux bold keeps antialiased edges at small sizes (#4130) by @vangel76 in #4360
  • Free Transform: refuse outputs over a pixel budget instead of building them by @itrycodinganditsbad in #4293
  • feat(ui): developer tile grid overlay (ui.set {"tileGrid": true}) by @deadmeu in #4217
  • Camera Raw Filter: save and load settings as .xmp by @FredApps in #4279
  • feat(ui): Photoshop's type formatting keys while editing text by @FinnNk in #4239
  • fix(io): read CS2 placed layers that carry only a PlLd block (#2465) by @Kartik8Dwivedi in #4268
  • Pen: show a close cue when hovering the first anchor (#4193) by @vangel76 in #4361
  • Type tool: spelling suggestions in the edit menu (#4370) by @vangel76 in #4375
  • Menus keep clear of a panel that covers a maximized window (X11) (#3737) by @FredApps in #4380
  • feat(codecs): open DDS textures, uncompressed and BC1-BC3 (#1327) by @marcoarnulfo in #4255
  • Color panel: the spectrum field in every theme (#4367) by @itsF4LCON in #4399
  • macOS: big brushes keep a native outline too, and big cursor bitmaps rasterise 7x faster (#1343) by @tanish2k09 in #4401
  • Save As: offer ICO, GIF and BMP in the file type list (#4357) by @itsF4LCON in #4405
  • Recent files: a saved document is listed, as an opened one is (#4400) by @itsF4LCON in #4411
  • Paths: curves stay smooth when zoomed in (#4084) by @dhiorns15 in #4445
  • Toolbar: click and hold on Change Screen Mode opens its modes (#4444) by @dhiorns15 in #4464
  • Puppet Warp: ⌘Z / ⌘⇧Z undo and redo pin edits (#4440) by @itsF4LCON in #4479
  • Crop tool: the drawing crosshair, not the move cursor, inside the untouched default frame by @marcoarnulfo in #4481
  • Clone Source: clip the overlay to a shaped brush tip (#4372) by @vangel76 in #4376
  • The wheel steps the options bar's Mode dropdown for Brush, Pencil and Gradient (#2061) by @megaDon101 in #4447
  • Pen: Auto Add/Delete anchors on the active path (#4144) by @bazmarth in #4540
  • Save As: on Windows, picking another file type changes the extension (#4394) by @dhiorns15 in #4407
  • Toolbar: no tooltips over an open tool flyout (#4450) by @dhiorns15 in #4469
  • Free Transform: apply a large layer's warp in the background, with progress and Esc to cancel (#1015) by @ianswope in #4218
  • Toolbar: a press outside a tool flyout closes it (#4460) by @dhiorns15 in #4480
  • Replace Color: a canvas eyedropper picks the From colour (#4143) by @mroxso in #4247
  • Allow toolbar tool shortcuts to be remapped by @RavoxX in #4194
  • Fix macOS system dialog localization by @Minischatten in #4261
  • Engine: reject unknown params for layer.hideLayers/showLayers, opt-in registry check (#4336) by @vangel76 in #4364
  • Preserve HDR and signed colors in 32-bit text rasterization by @jonathanwxh-cell in #4379
  • Type: fall back to installed Indic fonts for document text (#4383) by @vangel76 in #4386
  • Raw: treat DNG samples piled up below the stated white level as clipped by @marcoarnulfo in #4389
  • Content-Aware Move: live preview of the result (#4385) by @vangel76 in #4393
  • Swatches: an RGB group with the exact primaries and secondaries (#4302) by @FredApps in #4409
  • SVG: a group clipped by one path opens as editable shapes with a vector mask (#4266) by @itsF4LCON in #4425
  • Compose: key the vector-mask cache by content, not a temporary's address (#4426) by @vangel76 in #4428
  • Actions: record File › Save a Copy and play it back as a copy (#4373) by @itsF4LCON in #4390
  • Compose: no overflow or unbounded allocation on hostile coordinates (#4427) by @vangel76 in #4431
  • Smart Filters: select a filter, drag or ⌥-drag it onto another smart object (#4271) by @itsF4LCON in #4371
  • Add Krita (.kra) import with layers by @scottcampbelldata in #4388
  • i18n(sr): add a Serbian (Latin, Ekavian) UI catalog by @Dejan-Port in #4436
  • feat(ui): Linux caption buttons follow the desktop layout, style and icon theme by @sssehnsuchttt in #4439
  • Themes: Soft Dark and Soft Light (#4368) by @vangel76 in #4378
  • Type: type on a path, glyphs follow the curve (#4365) by @vangel76 in #4377
  • panic_hunt: don't fuzz the print commands into a real printer by @FabioLissi in #4467
  • Fix main: gate rayon in the tile grid overlay so the web build compiles by @echelon in #4694
  • Align tighter camera JPEGs for RAW colour fitting by @optimalbytee in #4598
  • Check peak RAW development memory and bound AHD scratch by @optimalbytee in #4597
  • Content-Aware Fill: no tinted blotch in a smooth gradient by @switch87 in #4708
  • Composited CMYK documents now export as CMYK TIFF and JPEG with their profile (#2220) by @KnottyDyes in #4199
  • Open Canon CR3 as labelled camera JPEG previews by @optimalbytee in #4595
  • Sample every visible layer in Content-Aware Fill by default. by @vbasky in #4133
  • Resize the Liquify brush with Alt+right-drag by @vbasky in #4707
  • Free Transform: the live preview feathers a linked layer mask by @marcoarnulfo in #4581
  • perf: reuse sampled composite across channel visibility toggles by @Ni-zav in #4080
  • Fix main: Serbian translations for the Soft themes by @echelon in #4727
  • Save for Web: no matte by default, as Photoshop's scripted export (#4115) by @itsF4LCON in #4578
  • Load Files into Stack: Photoshop's dialog with a Source Files list and the align option (#4671, #4696) by @itsF4LCON in #4705
  • Edit › Transform › Rotate and Skew no longer scale (#3941) by @vbasky in #3986
  • Open: warn about type in fonts that aren't installed (#4559) by @dhiorns15 in #4576
  • Status bar: wrap fullscreen zoom scrubbing at horizontal edges by @arthurdeka in #3983
  • Screen color picker: no DX12 crash, and the overlay can be left on Windows (#4443) by @zuujiscom in #4704
  • Add timeline playback to Save for Web previews by @jonathanwxh-cell in #4703
  • Free Transform: H and V skew fields in the options bar by @dhiorns15 in #4699
  • Channels: drag a channel onto New, Delete or Load Selection (#4689) by @dhiorns15 in #4693
  • Fit Image: the dialog is as narrow as its few fields by @marcoarnulfo in #4692
  • Move tool: the curved rotate arrow just outside its transform controls (#4658) by @itsF4LCON in #4687
  • perf(select): reuse run-table buffer in Feather horizontal pass by @rgoza1996 in #4632
  • Reject negative PSD style-sheet indexes by @vbasky in #4631
  • Keep the scrollbar thumb visible by @vbasky in #4630
  • Translate Turkish Amount as Miktar by @vbasky in #4629
  • Use a half-filled circle for adjustment thumbnails by @vbasky in #4628
  • Indent layer effects under their layer by @vbasky in #4627
  • Remove the dead gap between popup menu rows by @vbasky in #4624
  • Show (C)ancel on the unsaved-changes prompt by @vbasky in #4622
  • Apply Image: source layer, Scale and Offset in the dialog by @itrycodinganditsbad in #4574
  • feat(vector): add shape from selection with simplify tolerance (#214) by @seotarek in #3954
  • Channels: clicking RGB hides the alpha channel overlay by @marcoarnulfo in #4564
  • Fix: Preview pixelation in Sharpen filters by @AvrazAkraye in #3936
  • Brushes: a New Brush Preset dialog for every way of making a preset (#4490) by @itsF4LCON in #4563
  • fix(ui): expose custom paper dimensions in Print Settings by @zenjabba in #3893
  • Play real Photoshop action sets: TrueGrit .atn mappings and fixes (#4356, #219) by @VegaEX in #4698
  • New Document: blank presets follow the picked orientation and physical unit by @marcoarnulfo in #4686
  • Checkboxes: a pressed box shows it, as in Photoshop (#4476) by @dhiorns15 in #4553
  • fix(clipboard): prompt to save new documents containing pasted pixels by @Ni-zav in #4683
  • perf(text): applying preferences no longer waits for the system font scan (#4519) by @FinnNk in #4679
  • perf(ui): Channels thumbnails skip selection-only steps and reuse their textures (#4518) by @FinnNk in #4678
  • perf(engine): Fill, Stroke and Clear keep tiles the selection doesn't reach (#4517) by @FinnNk in #4677
  • Screen color picker: Esc, right-click and any click always end it (#4291) by @dhiorns15 in #4636
  • PSD save: keep the Lr16/Lr32 padding outside the block length by @marcoarnulfo in #4663
  • Filter dialogs: the preview keeps square pixels by @marcoarnulfo in #4655
  • Update Japanese translations in ja.tsv by @coolvitto in #4651
  • Cursors: the pen tools show their icon, and Caps Lock swaps it for the crosshair (#4639) by @dhiorns15 in #4650
  • Hue/Saturation: colour ranges apply in full to dull colours by @marcoarnulfo in #4645
  • Free Transform / Warp: Photoshop's Bicubic (Keys −0.75) and a reduction prefilter by @MrCloudy2 in #4635
  • Codecs: FITS keeps long CONTINUE strings intact on open and save by @webdevtodayjason in #4633
  • Layers panel: shape layers show a shape badge on their thumbnail (#4584) by @Higgs32584 in #4619
  • Brushes: Photoshop's measured round tip (hardness falloff and reach) by @MrCloudy2 in #4617
  • Gradient options bar: the swatch covers its checkerboard at half-pixel offsets by @marcoarnulfo in #4616
  • Layers panel menus: highlight the item a press-drag is over (#4601) by @itsF4LCON in #4607
  • Fill keys: Alt/Cmd+Backspace recolour the text of a type layer by @marcoarnulfo in #4606
  • Layers: right-clicking a layer-mask thumbnail opens the mask menu by @marcoarnulfo in #4605
  • Background Eraser: one pass clears the whole stroke by @itrycodinganditsbad in #4552
  • fix(engine): a pasted smart object keeps its PSD-embedded linked source (#3584) by @dottedt in #3608
  • CMYK: Invert, Posterize and Threshold on the inks; 16-bit Lab Invert keeps greys neutral by @timothydaly1 in #3930
  • fix(ui): click and hold on a toolbar button selects its tool (#4453) by @mjohnson7cd in #4544
  • OpenRaster: never overwrite an .ora with less than the document has (#3806) by @timothydaly1 in #3881
  • fix(ui): floating panel groups get an opaque title strip in Studio themes (#4509) by @mjohnson7cd in #4543
  • Fix main: duplicate Japanese rows and missing Serbian mask strings by @echelon in #4793
  • fix(text): preserve hyphenated PSD font identity on reopen by @zenjabba in #3878
  • feat(gpu): composite Blend If on the GPU (#4395) by @FinnNk in #4541
  • Pen: a close-path pointer over the first anchor (#4596) by @itsF4LCON in #4612
  • Color: Dot Gain 20%-compatible default working gray, as in Photoshop by @MrCloudy2 in #4610
  • perf(engine): Edit › Copy shares whole tiles instead of rebuilding them (#4516) by @FinnNk in #4621
  • Select › Sky: a white or grey backdrop that reaches the bottom is not sky by @switch87 in #4638
  • Properties: Align and Distribute with the Background in a multiple selection (#4608) by @itsF4LCON in #4637
  • Layers: Add vector mask makes the mask from the selected path and targets it by @marcoarnulfo in #4740
  • Handle signed coordinate limits in the Offset filter by @jonathanwxh-cell in #4738
  • perf(ui): Duotone and live-adjust display documents are built once per snapshot (#4527) by @FinnNk in #4736
  • Layers panel: clicking a row's lock icon unlocks the layer by @marcoarnulfo in #4734
  • perf(raster): mode and depth conversion keep shared tiles shared (#4531) by @FinnNk in #4725
  • feat(ui): bidirectional hover highlighting between Layers panel and canvas by @safvanedge in #4719
  • Filters: ⌘Z steps the open dialog's settings instead of the document by @marcoarnulfo in #4715
  • Keep close gradient stops on the CPU by @vbasky in #4712
  • perf(camera-raw): convert both previews in parallel bands (#4682) by @nicolasfalesy in #4757
  • perf(algo): filters read the selection once per tile when mixing it back (#4533) by @FinnNk in #4754
  • fix(batch): skip recorded Quick Export steps when writing batch output by @Ni-zav in #4747
  • fix(type): preserve keyboard focus when searching for fonts by @Ni-zav in #4745
  • feat(export): offer ICO in Export As with dimension validation by @Ni-zav in #4744
  • Fix print fuzzing and Windows crop GPU test fixtures by @Skyfuller1303 in #4726
  • feat(print): Printer menu lists the system's printers (file.printers) by @isaiahoadeoye-star in #4748
  • i18n(pt-br): fix 12 Brazilian Portuguese strings by @s17sh70x2jfl031ag in #4796
  • feat(new-document): add ISO B3 and B4 print presets by @Ni-zav in #4784
  • i18n(ru): fix counted status agreement and font weight labels by @VanTan666 in #4787
  • fix(input): support precision trackpad pinch zoom on Linux by @Ni-zav in #4786
  • Brush Settings: disable minimum inputs when Control is Off by @augrclk in #4775
  • Brush: the Mode dropdown shows in every theme, not only Pro by @marcoarnulfo in #4537
  • Channels: Channel Options dialog to make alpha channels spot colours (#3761) by @bommerts in #3784
  • fix(macos): default generated droplets to a user directory by @Ni-zav in #4746
  • fix(clipboard): paste JPEG, BMP and other non-PNG images on Wayland (#2546) by @nicolasfalesy in #4752
  • fix(format): contain directory-bundle symlinks without slow autosaves by @shmuelbiller1 in #3942
  • Scorecard: Smart Object corner skew and perspective is done (FILE-215-6, #426) by @FabioLissi in #5094
  • docs: credit Ufuk Efe in people.toml (#3809) by @yeniufuklar-com in #5056
  • Save for Web: JPEG chroma is full (4:4:4) above quality 50, as in Photoshop by @switch87 in #4823
  • Flat export: a Lab document with one layer isn't reported as flattened by @switch87 in #4853
  • TIFF: save uncompressed by default, like Photoshop by @marcoarnulfo in #4491
  • fix(segment): stop push/relabel looping forever on unreachable nodes by @LloydNicholson in #4869
  • PSD: a version 3 Photo Filter colour is XYZ relative to the D50 white (#4940) by @mroxso in #4987
  • Validate merged PSD channel indices before decoding by @Ni-zav in #4994
  • fix(psd): reserve imported layer IDs when allocating section dividers by @Ni-zav in #4885
  • fix(canvas): open small images at 100%, not at the display scale by @jyrkive in #5089
  • Brush Settings: no section title above the options pane (#3477) by @Higgs32584 in #5017
  • Save: a name without an extension gets the suggested one (#5039) by @mroxso in #5049
  • A file dropped on the canvas applies the open Free Transform and is placed at once by @marcoarnulfo in #4849
  • fix(ui): an open Free Transform box takes Zoom tool drags and clicks by @marcoarnulfo in #4808
  • Shapes: test that the options bar Fill swatch recolours the shape just drawn (#3997) by @itsF4LCON in #4510
  • Alerts: Enter is OK, but not the Enter that raised the alert (#4872) by @itsF4LCON in #4880
  • Toolbar: clicking a tool's button again closes its open flyout (#4932) by @dhiorns15 in #4937
  • Themes: default light theme to Pro Light to preserve the Pro layout (#5016) by @Sir-Starch in #5029
  • i18n(ru): translate dynamic selection, theme and measurement labels by @VanTan666 in #4838
  • Smart Filters: Delete removes the selected filter, not its smart object by @marcoarnulfo in #4764
  • Canvas: the CPU canvas shows crisp pixels when zoomed in by @marcoarnulfo in #4825
  • Layer Style applies an open Free Transform first, so its preview shows by @marcoarnulfo in #4835
  • fix(gradient): options-bar Opacity updates the live gradient layer (#5012) by @alonfaraj in #5045
  • Fix: native gesture fallback dedupe by @Ni-zav in #5080
  • Keep applied guide layouts visible after preview closes by @jonathanwxh-cell in #5084
  • Type options: the wheel over the font menu steps through the families (#3350) by @vangel76 in #3524
  • Navigator: one zoom row as in Photoshop: the percentage, Zoom Out, the slider and Zoom In (#4840) by @itsF4LCON in #4854
  • fix(ui): display uppercase hex values in the color picker by @Ni-zav in #4859
  • Pen: a new path joins the selected path instead of replacing the Work Path (#4721) by @itsF4LCON in #4730
  • Brush import: Dual Brush spacing comes from its tip (#4809) by @dhiorns15 in #4889
  • Fix Color Balance Preserve Luminosity with multiple midtone sliders by @Ni-zav in #4990
  • PNG: a whole-ppi pHYs reads back whole (300 ppi stays 300) by @switch87 in #4857
  • io: a tagged CMYK file's merged image reads through its own profile by @timothydaly1 in #4948
  • perf(raster): moving a layer no longer stores tiles of only the default pixel by @deadmeu in #4844
  • perf(gpu): closing a document frees what the compositor holds for it (#4529) by @FinnNk in #4772
  • Direct Selection: arrow keys nudge the selected anchors by @marcoarnulfo in #4500
  • Brushes: preset card size numbers stay clear of the tips (#4454) by @dhiorns15 in #4485
  • Shortcuts: ⌥⇧⌘N makes a new layer without the dialog (#4794) by @dhiorns15 in #4807
  • Brush Settings: use an amount slider for Hue Jitter by @augrclk in #4874
  • Keep custom title bar draggable while dialogs are open by @imSlicedBread in #4913
  • Assign Profile: list only profiles of the document's colour mode (#4951) by @Higgs32584 in #5020
  • Symmetry: Transform Symmetry gets commit/cancel buttons and its own cursors (#4495) by @dhiorns15 in #4508
  • Layers: Ctrl+Alt+G releases the clipping mask when pressed again, as in Photoshop by @OctaNebula in #4927
  • UI fonts: draw a variable CJK fallback at Regular, not Thin (#4820) by @dhiorns15 in #4830
  • Smart Filters: drag a filter up or down its stack to reorder it by @abc2cb in #4897
  • New Document: a custom background colour, from Custom… or the swatch beside the menu (#4789) by @itsF4LCON in #4801
  • Polygonal Lasso: drop the polygon on a document switch by @avdyliisni9-png in #5015
  • fix(ui): Match Color's preview reads the Source document (#4851) by @kavishkashehan726-sudo in #4886
  • Control: list and answer the unsaved-changes prompt (#4920) by @dhiorns15 in #4924
  • fix(ui): show a magnifier cursor for the Zoom tool on Windows (#3735) by @bommerts in #3783
  • Preset panels: the footer stays in view in a short dock group (#4790) by @dhiorns15 in #4824
  • perf(ui): the Navigator draws the GPU canvas's texture instead of a CPU thumbnail (#4518) by @FinnNk in #4701
  • Filters: Photoshop's Blur More kernel, Find Edges strength and Polar Coordinates direction by @MrCloudy2 in #4652
  • perf(compose): the shape stroke split cache keeps to a byte budget and empties on Purge (#4530) by @FinnNk in #4774
  • fix(gpu): invalidate pattern cache for default and format changes by @haranishi in #5013
  • Text: binary-search the run lookup and probe smcp once per layout (#4430) by @vangel76 in #4432
  • Palette PNGs open in Indexed Color mode with their colour table by @marcoarnulfo in #4817
  • fix(compose): redraw shapes crossing canvas bounds and include vector bounds in damage (#3946) by @seotarek in #4493
  • Distort: a quad dragged past the horizon draws only its front side, in the preview and the result (#4863) by @itsF4LCON in #4870
  • Select › Color Range: Skin Tones by @switch87 in #4473
  • Give Image Statistics a source-file dialog and stack mode selector by @jonathanwxh-cell in #4778
  • Pen: Ctrl/Cmd edits the path being drawn in place (#4022) by @bazmarth in #4526
  • Fix Export As freeze on large layered PSDs by @StopCodeToTrain in #5104
  • Preferences › Interface: Photoshop's Appearance / Presentation / Options layout (#2532) by @davidmann4 in #2589
  • Web: show the brush preset storage banner only while a change is unsaved by @kuvshin888 in #4918
  • Curves: points outside 0..255 are refused, as the message says by @switch87 in #4868
  • Clip Fill source reads to the canvas before allocating by @vbasky in #4590
  • Report allocation failures when clearing a color channel by @vbasky in #4589
  • Channels: keep the cached composite across view-only changes by @persi-man in #4915
  • info: adjustment layers are reported with the params their command takes by @switch87 in #4871
  • Preserve the document when Fade cannot allocate pixel buffers by @vbasky in #4593
  • feat(select): preserve existing mask metadata and allow explicit target in refineEdge by @seotarek in #4499
  • perf(paint): sampled tips share their samples, so cloning brush settings is cheap (#4534) by @FinnNk in #4798
  • fix(gpu): require consent to persist CPU recovery by @Ni-zav in #3539
  • Smart Objects › Export Contents: another extension exports the contents in that format by @switch87 in #4847
  • fix(window): reopen at the saved window position instead of re-centri… by @kavishkashehan726-sudo in #4850
  • Count document patterns in history budgets by @jonathanwxh-cell in #5105
  • info: a smart object embedded in a PSD is reported as embedded by @switch87 in #4843
  • Layer locks: locking the pixels clears the transparency lock, as in Photoshop (#4892) by @itsF4LCON in #4898
  • Swatches: importing an .ase file numbers repeated group names in linear time by @dotCooCoo in #5087
  • Layers: Cmd/Ctrl-click New Layer adds the layer below the current one by @seanhellwig in #4475
  • Docs: document the engine.commands reply shape (#3684) by @davidmann4 in #3750
  • perf(engine): lasso and polygon selections rasterise only the rows they span (#4532) by @FinnNk in #4773
  • Replace Color: Localized Color Clusters (points, localized, range) by @switch87 in #4477
  • perf: encode and quantize canvas pixels in parallel (display_color, Buffer::to_rgba8) by @nicolasfalesy in #4768
  • Puppet Warp: a linked layer mask moves with the pixels (#4910) by @DeWarePeb in #4989
  • fix(type): missing-font checks follow layout's PostScript resolution; split hyphenless style suffixes by @kijoong-kim in #608
  • Layer: Duplicate Layer to a new document, as in Photoshop by @abdul-karim-mia in #4805
  • History: jump to a state in one step (history.selectState) (#2966) by @davidmann4 in #3533
  • Wrap Clone Stamp strokes and sampling in Pattern Preview by @jonathanwxh-cell in #4997
  • Brush: remember the last selected brush across restarts (split from #2516) by @siraxe in #3472
  • Large document: full CPU canvas redraws run in the background, visible part first (#4024) by @ianswope in #5001
  • PSD: Backgrounds survive a round trip through PhotoCraft by @MrCloudy2 in #3560
  • fix(psd): prioritize 16-bit and 32-bit global layer blocks over compatibility section (#4928) by @Sir-Starch in #4950
  • fix(segment): let Remove Background's cancel stop Select Subject's min cuts by @LloydNicholson in #4878
  • Speed up Blur/Sharpen convolution while preserving exact output by @jonathanwxh-cell in #4511
  • Add filename templates to Batch export by @jonathanwxh-cell in #4466
  • Profile prompts on open: one file at a time, before it opens, and the answer goes to that file by @kayrockscreenprinting in #3471
  • Blur Gallery: Field Blur pins on the image (#3373) by @timothydaly1 in #3801
  • i18n(de): translate the labels that were still English (344 entries) and fix three display bugs by @DomiLuebben in #4008
  • Auto-Blend Stack Images: a depth map by depth from focus, for Lens Blur by @ragtux in #2073
  • PSD: parallel RLE for the merged image; layer channels decode and gather on all cores by @Elvis33LE in #2754
  • Speed up large-radius Unsharp Mask with guarded FFT convolution by @optimalbytee in #2987
  • Decode Panasonic RW2 RawFormat 3/4 (vendor-compressed sensor data) by @Gotya-OFFCIAL in #3286
  • Rulers: drag the zero point from the ruler corner, double-click resets it (#2955) by @davidmann4 in #3505
  • TIFF: write and read EXIF as the file's own Exif and GPS directories by @switch87 in #4876
  • fix(gpu): contain errors in unwatched compositor work by @haranishi in #4894
  • Deep EXR: open cropped renders on their full display-window stage by @Elvis33LE in #4907
  • Stroke layer effect: the outer edge stays round at wide sizes (#3646) by @dottedt in #3650
  • Stroke latency trace: PHOTOCRAFT_STROKE_TRACE times each frame of a brush stroke (#1343) by @tanish2k09 in #4403
  • Share native Windows driver settings and RGB printing through craft-print by @skylartaylor in #4599
  • Print on Windows: printer list, driver Print Settings, GDI printing by @Moiztermind in #3013
  • docs: write product name as PhotoCraft in development guide by @wwewtech in #5228
  • docs: drop stale missing-tool rows, only Art History Brush is missing by @LorenzoFasolino in #5063
  • Docs: oracle floor, open issues, workspace size and layer filters match main (#5376) by @Higgs32584 in #5382
  • PSD import: ResolutionInfo is pixels per inch whatever the display unit by @Zer0C00L01 in #5280
  • fix(prefs): preserve selected themes during legacy migration by @VanTan666 in #5179
  • Color Range presets: weigh dark colours like Photoshop (#5243) by @switch87 in #5293
  • Reject clipboard origins that cannot form a new document by @vbasky in #4586
  • Return channel copy allocation errors while keeping the clipboard by @vbasky in #4587
  • Check selection modification limits before reading the canvas mask by @vbasky in #4591
  • Background: an opacity, fill, blend mode or Select and Mask layer mask makes it Layer 0 by @switch87 in #4837
  • Fibers: fill an empty layer, as Photoshop does (#5241) by @switch87 in #5289
  • Object Selection: say so when the sampled layer is empty (#5246) by @switch87 in #5298
  • layer.setProps: refuse opacity and fill outside 0..1 (#5242) by @switch87 in #5291
  • test(engine): add Color Range fuzziness 0 exact-match test (TOOL-214-3) by @nicolasfalesy in #3581
  • panic_hunt: count panics that Session::execute contains (#4982) by @prekabreki in #5219
  • Drop shadow: knocked out beneath the whole shape when the layer's mode blends with it by @Deeev201 in #5304
  • Layer masks: Reveal Selection drops the selection, as Photoshop does by @abc2cb in #5251
  • PSD: Mt16/Mt32 blocks mark the merged image's transparency (no spurious Transparency channel) by @timothydaly1 in #5178
  • IO: ABR fit and gradient bake check their own bounds (io audit S1) by @vangel76 in #5218
  • Tests: bad-layer-id checks use an id that can't exist (#3343) by @vangel76 in #3351
  • fix(format): keep and list committed autosave bundles whose sidecar was never written (#4967) by @MarekSpodBiedry in #5076

New Contributors

  • @cloudalister made their first contribution in #3990
  • @FabioLissi made their first contribution in #4434
  • @marcoarnulfo made their first contribution in #4079
  • @aweussom made their first contribution in #4396
  • @Furash made their first contribution in #4105
  • @augrclk made their first contribution in #4463
  • @lucAmbr0 made their first contribution in #4290
  • @przemyslvw made their first contribution in #4104
  • @Hevarh1 made their first contribution in #4224
  • @dotCooCoo made their first contribution in #4054
  • @syncroot made their first contribution in #4062
  • @TheDankness made their first contribution in #4129
  • @xtellarvoid made their first contribution in #4337
  • @persi-man made their first contribution in #4314
  • @deadmeu made their first contribution in #4217
  • @megaDon101 made their first contribution in #4447
  • @bazmarth made their first contribution in #4540
  • @RavoxX made their first contribution in #4194
  • @Minischatten made their first contribution in #4261
  • @Dejan-Port made their first contribution in #4436
  • @sssehnsuchttt made their first contribution in #4439
  • @zuujiscom made their first contribution in #4704
  • @rgoza1996 made their first contribution in #4632
  • @AvrazAkraye made their first contribution in #3936
  • @VegaEX made their first contribution in #4698
  • @webdevtodayjason made their first contribution in #4633
  • @Higgs32584 made their first contribution in #4619
  • @safvanedge made their first contribution in #4719
  • @isaiahoadeoye-star made their first contribution in #4748
  • @VanTan666 made their first contribution in #4787
  • @jyrkive made their first contribution in #5089
  • @OctaNebula made their first contribution in #4927
  • @avdyliisni9-png made their first contribution in #5015
  • @haranishi made their first contribution in #5013
  • @StopCodeToTrain made their first contribution in #5104
  • @seanhellwig made their first contribution in #4475
  • @DeWarePeb made their first contribution in #4989
  • @abdul-karim-mia made their first contribution in #4805
  • @wwewtech made their first contribution in #5228
  • @LorenzoFasolino made their first contribution in #5063
  • @Zer0C00L01 made their first contribution in #5280
  • @Deeev201 made their first contribution in #5304
Full Changelog: v0.8.2...v0.9.0

Performance and Compatibility

PhotoCraft is built as a native Rust application rather than a web wrapper or Electron application. Its rendering architecture uses wgpu for GPU compositing with support for graphics APIs including Metal, Vulkan, DirectX 12 and WebGPU.

The application also uses multithreaded filters and copy-on-write sparse tiles. This design is intended to reduce unnecessary copying and make large layered documents more manageable.

The project reports extensive automated testing, including PSD round-trip tests, compositor comparisons and multi-depth testing. Its architecture also includes a CPU compositor used as a reference against the GPU compositor.

PhotoCraft can run natively on Windows, macOS, Linux and FreeBSD, with a WebAssembly build for browser use.

The main limitation is maturity. The developers explicitly describe the project as early alpha and acknowledge that it is not yet suitable as a complete replacement for Photoshop in professional daily workflows. Missing areas include AI and generative features, some tools, deeper typography and professional workflows, and plugin compatibility.

System Requirements

PhotoCraft supports:

  • Windows

  • macOS

  • Linux

  • FreeBSD

  • WebAssembly/browser

Linux distributions can use AppImage, DEB, RPM, tarball or Flatpak packages.

Hardware requirements are not presented as a simple minimum specification. Because PhotoCraft uses GPU acceleration, actual performance will depend heavily on the graphics hardware and the size and complexity of the documents being edited.

Pros and Cons

Pros

  • Open-source and available under permissive MIT or Apache-2.0 licensing

  • Native Rust application

  • No Electron or embedded web browser required

  • Excellent focus on PSD compatibility

  • Extensive layer and adjustment-layer support

  • GPU-accelerated rendering

  • Supports CMYK, Lab and high-bit-depth documents

  • Strong brush and vector capabilities

  • Windows, macOS, Linux and FreeBSD support

  • Can also run through WebAssembly

  • Powerful CLI and automation capabilities

  • MCP support makes it interesting for AI-assisted workflows

  • Offline-first approach

Cons

  • Still early alpha

  • Not yet a complete Photoshop replacement

  • Missing some tools and professional workflows

  • No Photoshop plugin compatibility

  • AI and generative editing features are limited or absent

  • Typography capabilities are not yet as mature as established professional editors

  • Some rough edges should be expected

How to Install

The easiest approach is to download the appropriate package from the project's GitHub releases.

Linux users have several packaging options, including AppImage, DEB, RPM, tarball and Flatpak. Windows has a portable package, while macOS has a universal disk image.

Developers can also build PhotoCraft directly from source using Rust:

git clone https://github.com/storytold/photocraft
cd photocraft
cargo run --release -p photocraft -- image.psd

The repository also provides CLI functionality for automated editing and batch processing.

Final Verdict

PhotoCraft is one of the more ambitious open-source Photoshop alternatives currently available. Its combination of native Rust performance, extensive layer support, serious PSD compatibility work and an unusually capable automation architecture makes it much more than a basic image editor.

The strongest reason to watch PhotoCraft is its engineering approach. The project is building a real image-editing engine rather than simply creating a Photoshop-like interface, and its extensive PSD testing provides a useful foundation for compatibility.

The biggest problem is maturity. The project itself acknowledges that it is still early alpha and lacks several areas required for professional Photoshop replacement workflows. Users who depend on plugins, advanced typography, AI features or highly polished production workflows should not switch completely yet.

For enthusiasts, developers, Linux users, open-source advocates and anyone interested in building automated image-processing workflows, however, PhotoCraft is particularly compelling.

PhotoCraft v0.9.0
Free
Software Informations:
Developer:

Operating System:
Windows / macOS / Linux / BSD
Date Added:
2026-10-14T21:07:13.234Z
Categories:

Post a Comment/Report Broken Link: