---
title: "Convert PSD to PNG in C#"
url: https://recursiveai.org/oneimage/articles/psd-to-png-csharp/
description: "Read Photoshop PSD and PSB files in C# with pure .NET code: convert PSD to PNG, JPG or WebP, list and export layers, hide a layer and save the PSD back."
date: 2026-10-26
author: OneImage team
---

# Convert PSD to PNG in C#

Read Photoshop PSD and PSB files in C# with pure .NET code: convert PSD to PNG, JPG or WebP, list and export layers, hide a layer and save the PSD back.

October 26, 2026 · OneImage team

To convert a PSD file to PNG in C#, add the OneImage.Psd package, register its format and load the file like any other image, then save it as `.png`. You get the whole document as Photoshop composited it, and the same call converts to JPG or WebP or makes a thumbnail. To work with the layers themselves, `PsdFile.Load` returns the layer tree, which you can list, export, change, render and save back as a PSD. Everything is pure .NET code, with no Photoshop, ImageMagick or other native binaries, on Windows, Linux, macOS and in containers. Every sample was run against OneImage 1.10.2 on .NET 10.

*Terminal · NuGet*

```
dotnet add package RecursiveAI.OneImage
dotnet add package RecursiveAI.OneImage.Psd
```

The examples use `layer_effects.psd`, an 800×640 Photoshop file with twelve layers that each show a layer effect, from the test files of the MIT-licensed [psd-tools](https://github.com/psd-tools/psd-tools) project.

## Convert a PSD file to PNG

*Program.cs · .NET 10*

```
using OneImage;
using OneImage.Psd;
 
// PSD comes in its own package: register it once and reuse the options.
var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(PsdFormat.Instance),
};
 
// The merged image: the whole document as Photoshop composited it.
Image.Load("layer_effects.psd", options).Save("layer_effects.png");
```

This wrote an 800×640 PNG of the whole design. PSD support lives in a separate package, so its format isn’t in OneImage’s default configuration: you add `PsdFormat` to an `ImageConfiguration` and pass it when you load. Saving needs nothing extra, because PNG, JPEG, WebP, GIF, TIFF, BMP and ICO are built in.

A PSD file can carry a merged copy of the whole document, and when it does, that is what `Image.Load` returns, so the result matches what Photoshop showed when the file was saved. A file without one is drawn from its layers instead. Large-document PSB files load the same way. Bitmap, gray, duotone, indexed, RGB, CMYK and Lab documents load; gray and RGB keep 8, 16 or 32 bits per channel, and CMYK and Lab are converted to RGB through the color engine.

## Convert PSD to JPG or WebP, and make thumbnails

*Program.cs · .NET 10*

```
using OneImage;
using OneImage.Psd;
 
var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(PsdFormat.Instance),
};
Image design = Image.Load("layer_effects.psd", options);
 
// JPEG has no transparency: put the image on white first.
design.Flatten(new Rgba32(255, 255, 255, 255)).Save("layer_effects.jpg");
 
// A 400 px wide WebP preview, in sRGB and without metadata.
Image.Thumbnail(design, 400).Save("layer_effects-400.webp");
```

The JPEG is 800×640 and the WebP preview 400×320. `Flatten` puts a transparent design on a white background first, because JPEG can’t store transparency. `Image.Thumbnail` accepts a loaded image too, so the PSD format you registered applies. It resizes, converts to sRGB and leaves out metadata, which is what you want for web previews and asset browsers. Our page on [converting images to WebP](https://recursiveai.org/oneimage/articles/convert-image-to-webp-csharp/) covers the quality settings.

## Read the size of a PSD without decoding it

*Program.cs · .NET 10*

```
using OneImage;
using OneImage.Psd;
 
var options = new LoadOptions
{
    Configuration = new ImageConfiguration().Add(PsdFormat.Instance),
};
 
// Reads the header only.
ImageInfo info = Image.Identify("layer_effects.psd", options);
Console.WriteLine($"{info.Format.Name} {info.Width}x{info.Height}");
```

This printed `psd 800x640` after reading only the header, which is a cheap check before you accept an upload or queue a conversion.

## Read the layers of a PSD file

*Program.cs · .NET 10*

```
using OneImage.Layers;
using OneImage.Psd;
 
using PsdFile psd = PsdFile.Load("layer_effects.psd");
Console.WriteLine($"{psd.Document.Width}x{psd.Document.Height}, {psd.SourceColorMode}, {psd.SourceBitDepth}-bit");
 
// Walk the layer tree, groups included.
void Print(GroupLayer group, int depth)
{
    foreach (Layer layer in group.Children)
    {
        string hidden = layer.Visible ? "" : " (hidden)";
        Console.WriteLine($"{new string(' ', depth * 2)}{layer.Kind} \"{layer.Name}\" {layer.Bounds.Width}x{layer.Bounds.Height}{hidden}");
        if (layer is GroupLayer child)
        {
            Print(child, depth + 1);
        }
    }
}
 
Print(psd.Document.Root, 0);
```

*Output · 1.10.2*

```
800x640, Rgb, 8-bit
Pixel "Background" 800x640
Pixel "Bevel" 190x47
Pixel "Emboss" 270x47
Pixel "Outer Glow" 399x48
Pixel "Inner Glow" 384x48
Pixel "Inner Shadow" 484x48
Pixel "Color Fill" 481x60
Pixel "Drop Shadow" 465x59
Pixel "Gradient Overlay" 600x60
Pixel "Pattern Overlay" 555x60
Pixel "Stroke" 232x48
Pixel "Satin" 180x48
```

`PsdFile.Load` parses the whole layer structure into a document model: pixel layers, groups, fill layers and adjustment layers, each with its name, visibility, opacity, blend mode, mask and bounds. Groups nest, so the sample walks them recursively. On a file with groups, such as the face drawing in the same test set, it printed the `Group` lines with their children indented below them. `PsdFile` is disposable, so wrap it in `using`.

## Export each layer as a PNG

*Program.cs · .NET 10*

```
using OneImage.Layers;
using OneImage.Psd;
 
using PsdFile psd = PsdFile.Load("layer_effects.psd");
Directory.CreateDirectory("layers");
 
int index = 0;
foreach (Layer layer in psd.Document.Root.Children)
{
    index++;
    if (layer is PixelLayer pixelLayer)
    {
        // The layer's own pixels, at the size of the layer, not of the document.
        pixelLayer.Pixels.Snapshot().Save($"layers/{index:00} {layer.Name}.png");
    }
}
```

This wrote twelve PNGs: the 800×640 background and eleven text layers cut to their own bounds, such as 465×59 for “Drop Shadow”. A pixel layer’s `Pixels` is an editable canvas, and `Snapshot()` takes an immutable image of it at no cost. The export holds the layer’s own pixels, without the effects that are drawn when the document is composited. To place a layer back at its position in the document, its `Bounds` gives the offset. Layer names can contain characters that aren’t allowed in file names, so clean them up if your files come from users.

## Hide a layer, render and save the PSD

*Program.cs · .NET 10*

```
using OneImage.Layers;
using OneImage.Psd;
 
using PsdFile psd = PsdFile.Load("layer_effects.psd");
 
// Hide the background and draw the document again from its layers.
foreach (Layer layer in psd.Document.Root.Children)
{
    if (layer.Name == "Background")
    {
        layer.Visible = false;
    }
}
 
psd.Document.Render().Save("no-background.png");
 
// Or keep it as a Photoshop file, with the change.
psd.Save("no-background.psd");
```

`Render()` composites the document from its layers with blend modes, opacity, masks, clipping, adjustment layers and the common layer effects (drop and inner shadows, glows, strokes, overlays, bevels and satin), so the PNG shows the design without its gray background, on transparency. `PsdFile.Save` writes the change back to a Photoshop file. What the model doesn’t edit, such as text and smart objects, keeps its stored pixels and data and is written back unchanged. An independent PSD reader opened the saved file and showed its merged image with the background gone: the corner pixel that was gray is now transparent. The [PSD documentation](https://github.com/recursive-ai-oss/oneimage-csharp/blob/main/docs/psd.md) lists what is modelled in detail and how renders compare with Photoshop’s own composites.

## PSD files from users

PSD is a large binary format, and a malformed file can claim huge layers or deep nesting in a few bytes. The reader is managed, bounds-checked code, and it checks every size against limits before allocating: at most 20,000 layers, 64 levels of group nesting and 64 MiB for one data block by default, plus OneImage’s usual pixel limits. A file over a limit fails with a typed exception instead of exhausting memory. To tighten them for uploads, pass a `PsdLimits` to `new PsdFormat(...)`, or set `PsdLimits` and `Limits` on the `PsdReadOptions` you give `PsdFile.Load`.

## Other ways to read PSD in C#

- **[Aspose.PSD](https://products.aspose.com/psd/net/)** is a commercial library that, in its NuGet description, manipulates PSD and PSB files and exports them to formats such as PNG, JPEG, GIF and TIFF. Its license is paid; see the [Aspose.PSD price list](https://purchase.aspose.com/pricing/psd/net/).
- **[PsdSharp](https://www.nuget.org/packages/PsdSharp/1.2.0)** 1.2.0 (October 2025) is an MIT-licensed managed library that, in its NuGet description, reads and renders PSD and PSB files. It targets .NET Standard 2.0 and .NET 6, so it fits projects that can’t move to .NET 10.

OneImage reads SVG and PDF the same way, through the [OneImage.Svg](https://recursiveai.org/oneimage/articles/svg-to-png-csharp/) and [OneImage.Pdf](https://recursiveai.org/oneimage/articles/pdf-to-image-csharp/) packages. For the core formats and operations, start at the [OneImage overview](https://recursiveai.org/oneimage/).
