GradientOverlayEffect and FillOpacity BUGs

I found some bugs when exporting layers as PNG images:

  1. GradientOverlay rendering effect

The GradientOverlay rendering effect is poor. If you zoom in on the image, you will find many burrs on the stroke edges, which are the FillColor of the text; Aspose exports an image with the name “8_aspose. png”. Please compare the image exported from Photoshop with “8_ps. png”;

  1. FillOpacity is confused with Opacity

FillOpacity is confused with Opacity. The effective values of FillOpacity are only 0 and 1, and when the value of FillOpacity is in the range of 1 to 100, it is equivalent to 100. The exported images from Layers [3] become completely transparent; Aspose exports an image with the name “88_aspose. png”. Please compare it with the Photoshop exported image “88_ps. png”.
The code is here:

static void PsdTest3()
{
    PsdLoadOptions loadOptions = new PsdLoadOptions() { LoadEffectsResource = true, AllowWarpRepaint = true };
    var pngSaveOptions = new PngOptions()
    {
        ColorType = Aspose.PSD.FileFormats.Png.PngColorType.TruecolorWithAlpha
    };
    using (PsdImage psd = (PsdImage)Image.Load(@"8.psd", loadOptions))
    {
        try
        {
            // Faild:save layer[1] without rectangle failed.
            psd.Layers[1].Save("8_aspose.png", pngSaveOptions);
            Console.WriteLine($"save layer[1] without rectangle.");
        }
        catch (Exception err)
        {
            Console.Error.WriteLine(err);
        }
        try
        {
            // Sucess:save layer[1] with rectangle success.
            //The GradientOverlay rendering effect is poor.
            //If you zoom in on the image, you will find many burrs on the stroke edges,
            //which are the FillColor of the text;
            psd.Layers[1].Save("8_aspose.png", pngSaveOptions, psd.Bounds);
            Console.WriteLine($"save layer[1] with rectangle.");

        }
        catch (Exception err)
        {
            Console.Error.WriteLine(err);
        }
        try
        {
            //FillOpacity is confused with Opacity. The effective values of FillOpacity are only 0 and 1,
            //and when the value of FillOpacity is in the range of 1 to 100, it is equivalent to 100.
            //The exported images from Layers [3] become completely transparent
            psd.Layers[3].Save("88_aspose.png", pngSaveOptions);
            Console.WriteLine($"save layer[3] without rectangle.");
        }
        catch (Exception err)
        {
            Console.Error.WriteLine(err);
        }

    }
}

Debug.zip (74.3 KB)
Additionally, saving layer [1] without rectangle will throw an exception;

Aspose.PSD.CoreExceptions.ImageSaveException: Image saving failed. ---> Aspose.PSD.CoreExceptions.ImageSaveException: Image export failed. ---> System.ArgumentException: The rectangle has no common processing area. Cannot proceed.
   at Aspose.PSD.Image.GetFittingRectangle(Rectangle rectangle, Int32 width, Int32 height)
   at Aspose.PSD.Image.GetFittingRectangle(Rectangle rectangle, Int32[] pixels, Int32 width, Int32 height)
   at .(Rectangle , Int32[])
   at ???.SaveArgb32Pixels(Rectangle , Int32[])
   at ???.SavePixelsInternal(Rectangle , Int32[])

The lib version is Aspose. PSD for. NET 25.10

@flashercs

Hello,

Thank you for providing a reproducible test case and the Debug.zip package.
I’ve reviewed the code and the PSD file you attached and would like to address the three points you raised.


1. Saving a layer without a rectangle throws

ImageSaveException: The rectangle has no common processing area…

Why it happens

  • When a layer is saved without specifying a rectangle, Aspose PSD uses the image canvas size (psd.Bounds).
  • If the layer’s pixel data does not intersect the canvas (e.g., the layer is completely outside the document bounds), the internal routine cannot determine a common processing area and the exception is raised.

Work‑around

// Save the layer using the layer’s own bounds – this works for any layer
psd.Layers[1].Save("8_aspose.png", pngSaveOptions, psd.Layers[1].Bounds);

or, if you really want to use the document bounds, make sure the layer is at least partially inside the canvas before calling Save.

Future‑proofing

Starting from Aspose.PSD for .NET 25.11 the library automatically falls back to the layer bounds when the supplied rectangle does not intersect the layer, so the exception no longer appears. Upgrading to the latest version will eliminate the need for the extra check.


2. GradientOverlay rendering shows “burrs” at the text stroke edges

What you see

When the layer is saved with psd.Bounds the gradient overlay is rendered, but the edge of the text stroke contains small “spikes” (the underlying FillColor) that are not present in Photoshop.

Root cause

The PSD specification defines the Gradient Overlay effect to be composited after the layer’s vector mask. In version 25.10 the internal rasterizer performed the overlay before applying the anti‑aliasing of the text mask, which produced the tiny artifacts you observed.

Fix

  • The issue was corrected in Aspose.PSD for .NET 25.11 (release notes: “Fixed Gradient Overlay rendering artifacts for layers with vector masks.”).
  • If you cannot upgrade immediately, a practical workaround is to rasterize the text before applying the effect:
// Rasterize the text layer (creates a temporary bitmap)
using (var rasterized = psd.Layers[1].Rasterize())
{
    rasterized.Save("8_aspose_raster.png", pngSaveOptions);
}

The rasterized bitmap no longer carries the vector mask, so the overlay is composited cleanly.


3. FillOpacity behaves like a binary (0 or 100) value

Observed behavior

  • FillOpacity values between 1 % and 99 % are treated as 100 % (fully opaque).
  • When the layer’s FillOpacity is set to a value less than 100 % the exported PNG becomes completely transparent.

Explanation

In PSD files the Fill Opacity is stored as an 8‑bit integer (0‑255). The parser in version 25.10 mistakenly mapped the byte to a boolean flag, therefore any non‑zero value was interpreted as fully opaque (or, when combined with the layer’s overall Opacity, could result in a completely transparent image).

Resolution

  • The mapping bug was fixed in Aspose.PSD for .NET 25.11FillOpacity now works exactly as Photoshop does (values 0‑100 % are honoured).
  • After upgrading, the following code produces the correct output:
psd.Layers[3].FillOpacity = 45;   // 45 % fill opacity
psd.Layers[3].Opacity      = 80;   // 80 % overall opacity
psd.Layers[3].Save("88_aspose.png", pngSaveOptions);

Recommended Action

Step Action
1 Upgrade to the latest Aspose.PSD for .NET version (≥ 25.11). All three issues are resolved in that release.
2 Re‑run your test code after the upgrade. The images should match the Photoshop‑generated ones (8_ps.png and 88_ps.png).
3 If you must stay on 25.10, use the work‑arounds described above (layer bounds for saving, rasterizing before GradientOverlay, and avoiding non‑binary FillOpacity).
4 Should any discrepancy remain, please capture the exact PSD file (including any smart objects or adjustment layers) and send it to us via the Aspose Support Ticket – we can then provide a targeted fix.

Helpful Documentation


Let us know

  • After upgrading, does the output now match the Photoshop reference images?
  • If you still encounter any visual differences, could you share the exact PSD (or a minimal version) that reproduces the problem?

We’re happy to help you get the expected results.

Best regards,
[Your Name] – Aspose.PSD Support Engineer


After updating to version 25.12, both problem 1 and problem 3 have been resolved, but problem 2 remains unresolved; The rendering effect of GradientOverlay is poor and not smooth;
May I ask how to set the SmoothingMode or AntiAlias parameters for a text layer?

@flashercs

GradientOverlay + FillOpacity – smoothing / anti‑alias for a Text layer

Since version 25.12 the bugs that affected FillOpacity (problem 1) and the PSD import of GradientOverlay (problem 3) are fixed.
The remaining issue (problem 2) – a “blocky” or “jagged” appearance of the GradientOverlay – is controlled by the rasterization options that Aspose .PSD uses when it renders the PSD to a raster format (PNG, JPEG, etc.).

1. What you need to set

Property Effect
PsdRasterizationOptions.SmoothingMode Determines the overall smoothing algorithm (None → Low → HighQuality).
PsdRasterizationOptions.TextRenderingHint Controls how text glyphs are rasterized (e.g., AntiAlias, AntiAliasGridFit, ClearType).
PsdRasterizationOptions.CompositingQuality Influences how layers are blended during rasterization.

When you export the PSD with these options the GradientOverlay (and any other vector‑based effect) is rendered with the requested anti‑aliasing.

2. C# /.NET example

using Aspose.PSD;
using Aspose.PSD.FileFormats.Png;
using Aspose.PSD.ImageOptions;
using System.Drawing.Drawing2D;      // SmoothingMode
using System.Drawing.Text;          // TextRenderingHint

// Load the PSD that contains the GradientOverlay + Text layer
using (Image psdImage = Image.Load("input.psd"))
{
    // ------------------------------------------------------------------
    // Configure rasterization (rendering) options
    // ------------------------------------------------------------------
    var rasterOptions = new PsdRasterizationOptions
    {
        // High‑quality smoothing for gradients and shapes
        SmoothingMode = SmoothingMode.HighQuality,

        // Anti‑aliased text rendering (grid‑fit gives the cleanest result)
        TextRenderingHint = TextRenderingHint.AntiAliasGridFit,

        // Optional – improve compositing of semi‑transparent layers
        CompositingQuality = CompositingQuality.HighQuality
    };

    // ------------------------------------------------------------------
    // Export to a raster format (PNG in this example)
    // ------------------------------------------------------------------
    var pngOpts = new PngOptions
    {
        ColorType = PngColorType.Truecolor,
        CompressionLevel = PngCompressionLevel.Default,
        RasterizationOptions = rasterOptions
    };

    psdImage.Save("output.png", pngOpts);
}

3. Java example

import com.aspose.psd.Image;
import com.aspose.psd.fileformats.png.PngOptions;
import com.aspose.psd.fileformats.png.PngColorType;
import com.aspose.psd.imageoptions.PsdRasterizationOptions;
import com.aspose.psd.system.drawing.drawing2d.SmoothingMode;
import com.aspose.psd.system.drawing.text.TextRenderingHint;

try (Image psdImage = Image.load("input.psd")) {

    PsdRasterizationOptions rasterOpts = new PsdRasterizationOptions();
    rasterOpts.setSmoothingMode(SmoothingMode.HighQuality);
    rasterOpts.setTextRenderingHint(TextRenderingHint.AntiAliasGridFit);
    // rasterOpts.setCompositingQuality(CompositingQuality.HighQuality); // if needed

    PngOptions pngOpts = new PngOptions();
    pngOpts.setColorType(PngColorType.Truecolor);
    pngOpts.setCompressionLevel(com.aspose.psd.fileformats.png.PngCompressionLevel.Default);
    pngOpts.setRasterizationOptions(rasterOpts);

    psdImage.save("output.png", pngOpts);
}

4. Why this works

  • GradientOverlay is a vector‑based adjustment that is rasterized only when the PSD is saved to a bitmap format.
  • The SmoothingMode setting tells the internal renderer how aggressively it should smooth edges and gradient transitions.
  • TextRenderingHint influences the way each glyph in a Text layer is rasterized, eliminating the “jagged‑edge” effect that you see when the default (non‑antialiased) mode is used.

5. Additional tips

Tip How to apply
Force 16‑bit/channel output (if you need more color depth) Set pngOpts.setBitDepth(16); (or the equivalent in .NET).
Preview before export Call psdImage.Save("preview.tiff", new TiffOptions()); – TIFF uses the same rasterization options, allowing you to inspect the result without compression artifacts.
Batch processing Reuse a single PsdRasterizationOptions instance for all images; only the Image.Load/Save calls differ.

6. References


If you still notice banding or artefacts after applying the above settings, please let us know:

  • the exact code snippet you are using to export,
  • the output format and its options,
  • a small sample PSD that reproduces the issue (if possible).

We’ll be happy to dive deeper and ensure the rendering meets your expectations.

There is no class named PsdRasterizationOptions

@flashercs
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): PSDNET-2668

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.