Browse our Products

Aspose.PSD for .NET 25.9 - Release Notes

KeySummaryCategory
PSDNET-2382Create for PSD load options a parameter that gives the ability to edit XmpData in Read-Only ModeFeature
PSDNET-2284[AI Format] Investigate an AIImage rendering problem that appears on macOSBug
PSDNET-2300The saved PSD file cannot be openedBug
PSDNET-2431The error: Image saving failed in the file with Artboard LayersBug
PSDNET-2449A specific PSD file can not be exported to BMP formatBug
PSDNET-2505Replacement of a smart object using an image instead of a path doesn’t workBug
PSDNET-2506Transparency lost after replacing smart object layersBug
PSDNET-2515Broken PSD file after exportBug
PSDNET-2541[Regression] Fix freeze on export AiImage while parsing of EPSF filesBug
PSDNET-2543Missed the Header of AiImageBug
PSDNET-2544Vertically inverted text rendering when exporting from AiImage [NET7.0+]Bug

Public API Changes

Added APIs:

  • F:Aspose.PSD.FileFormats.Psd.Layers.LayerMaskFlags.UserOrVectorMasksHaveParameters
  • P:Aspose.PSD.ImageLoadOptions.PsdLoadOptions.ReadOnlyType
  • T:Aspose.PSD.ImageLoadOptions.ReadOnlyMode
  • F:Aspose.PSD.ImageLoadOptions.ReadOnlyMode.None
  • F:Aspose.PSD.ImageLoadOptions.ReadOnlyMode.Default
  • F:Aspose.PSD.ImageLoadOptions.ReadOnlyMode.MetadataEdit

Removed APIs:

  • None

Usage examples:

PSDNET-2284. [AI Format] Investigate an AIImage rendering problem that appears on macOS

// This test is for non-Windows platforms.
string sourceFile = Path.Combine(baseFolder, "ai_one.ai");
string outputFile = Path.Combine(outputFolder, "ai_one.png");

using (AiImage image = (AiImage)Image.Load(sourceFile))
{
    image.Save(outputFile, new PngOptions());
}

PSDNET-2300. The saved PSD file cannot be opened

/// Check that after replacement of psdIme.Layers collection the saved file is correctly saved.

string inputFile = Path.Combine(baseFolder, "ZNDX.psd");
string replaceFile = Path.Combine(baseFolder, "TRF6242.png");
string outputFile = Path.Combine(outputFolder, "output.psd");

using (var psdImage = (PsdImage)Image.Load(inputFile, new PsdLoadOptions()))
{
    using (FileStream stream = new FileStream(replaceFile, FileMode.Open))
    {
        SmartObjectLayer smartObjectLayer = new SmartObjectLayer(stream);
        List<Layer> layers = new List<Layer>(psdImage.Layers);

        if (layers.Count > 0)
        {
            layers.RemoveAt(0);
        }

        layers.Insert(0, smartObjectLayer);
        psdImage.Layers = layers.ToArray();

        // Check link data sources count after Layers collection change.
        // It should be 1. Old data source is deleted with old smart layer,
        // new data source appended with new smart layer.
        var lnk2Resource = psdImage.GlobalLayerResources[1] as Lnk2Resource;
        AssertAreEqual(1, lnk2Resource.DataSourceCount);

        // The Saved psd file should be readable by PS.
        psdImage.Save(outputFile);
    }
}

void AssertAreEqual(object expected, object actual, string message = null)
{
    if (!object.Equals(expected, actual))
    {
        throw new Exception(message ?? "Objects are not equal.");
    }
}

PSDNET-2382. Create for PSD load options a parameter that gives the ability to edit XmpData in Read-Only Mode

string sourceFile = Path.Combine(baseFolder, "psdnet2382.psd");
string outputFile = Path.Combine(outputFolder, "output.psd");

string testMetadata = "Updated metadata text";

using (PsdImage psdImage = (PsdImage)Aspose.PSD.Image.Load(sourceFile,
    new PsdLoadOptions() { ReadOnlyType = ReadOnlyMode.MetadataEdit })) // Sets the of ReadOnlyMode to true
{
    AssertAreNotEqual(testMetadata, psdImage.XmpData.Meta.AdobeXmpToolkit);

    // Change metadata in ReadOnlyMode
    psdImage.XmpData.Meta.AdobeXmpToolkit = testMetadata;

    // Save changed metadata in ReadOnlyMode
    psdImage.Save(outputFile);
}

using (PsdImage psdImage = (PsdImage)Aspose.PSD.Image.Load(outputFile)) // Sets the of ReadOnlyMode to true
{
    AssertAreEqual(testMetadata, psdImage.XmpData.Meta.AdobeXmpToolkit);
}

void AssertAreEqual(object expected, object actual)
{
    if (!object.Equals(expected, actual))
    {
        throw new Exception("Objects should be equal, but they don't.");
    }
}

void AssertAreNotEqual(object obj1, object obj2)
{
    if (object.Equals(obj1, obj2))
    {
        throw new Exception("Objects should not be equal, but they are equal.");
    }
}

PSDNET-2431. The error: Image saving failed in the file with Artboard Layers

string sourceFile = Path.Combine(baseFolder, "2431_src_file.psd");
string outputFile = Path.Combine(outputFolder, "output.psd");

using (var image = Image.Load(sourceFile))
{
    if (image is PsdImage psdImage)
    {
        var imageOptions = new PsdOptions(psdImage);
        psdImage.Save(outputFile, imageOptions);
    }
}

PSDNET-2449. A specific PSD file can not be exported to BMP format

string inputFile = Path.Combine(baseFolder, "06-01-2.psd");
string outputFile = Path.Combine(outputFolder, "output.bmp");

using (var image = Image.Load(inputFile))
{
    // There should be no exception on Save.
    image.Save(outputFile, new BmpOptions());
}

PSDNET-2505. Replacement of a smart object using an image instead of a path doesn’t work

string sourceFile = Path.Combine(baseFolder, "B.psd");
string replacementImagePath = Path.Combine(baseFolder, "logo.png");
string outputFile = Path.Combine(outputFolder, "output.png");

var layerName = "GC-LARGE";

var loadOptions = new PsdLoadOptions
{
    LoadEffectsResource = true,
    AllowWarpRepaint = true
};

using (var image = (PsdImage)Image.Load(sourceFile, loadOptions))
{
    foreach (var layer in image.Layers)
    {
        if (layer.Name == layerName)
        {
            var smartLayer = layer as SmartObjectLayer;
            if (smartLayer == null)
            {
                break;
            }

            var resolution = new ResolutionSetting(96, 96);

            using (var rep = Image.Load(replacementImagePath))
            {
                smartLayer.ReplaceContents(rep, resolution);
            }

            smartLayer.UpdateModifiedContent();
            break;
        }
    }

    image.Save(outputFile, new PngOptions { ColorType = PngColorType.TruecolorWithAlpha });
}

PSDNET-2506. Transparency lost after replacing smart object layers

string sourceFile = Path.Combine(baseFolder, "B.psd");
string replacementImagePath = Path.Combine(baseFolder, "logo.png");
string outputFile = Path.Combine(outputFolder, "output.png");

var layerName = "GC-LARGE";

var loadOptions = new PsdLoadOptions
{
    LoadEffectsResource = true,
    AllowWarpRepaint = true
};

using (var image = (PsdImage)Image.Load(sourceFile, loadOptions))
{
    foreach (var layer in image.Layers)
    {
        if (layer.Name == layerName)
        {
            var smartLayer = layer as SmartObjectLayer;
            if (smartLayer == null)
            {
                break;
            }

            var resolution = new ResolutionSetting(96, 96);

            smartLayer.ReplaceContents(replacementImagePath, resolution);

            smartLayer.UpdateModifiedContent();
            break;
        }
    }

    image.Save(outputFile, new PngOptions { ColorType = PngColorType.TruecolorWithAlpha });
}

PSDNET-2515. Broken PSD file after export

string inputFile = Path.Combine(baseFolder, "smart_Test.psd");
string replaceFile = Path.Combine(baseFolder, "newImage.png");
string outputFile = Path.Combine(outputFolder, "export.psd");

using (var psdImage = (PsdImage)Image.Load(inputFile))
{
    SmartObjectLayer smartObjectLayer = (SmartObjectLayer)psdImage.Layers[1];

    // Source state of a Smart Object layer
    AssertIsNotNull(smartObjectLayer.Resources[9] as PlLdResource);
    AssertIsNotNull(smartObjectLayer.Resources[10] as SoLdResource);
    AssertIsNotNull(smartObjectLayer.Resources[11] as FxrpResource);
    var lnk2Resource = psdImage.GlobalLayerResources[1] as Lnk2Resource;
    var lnkeResrource = psdImage.GlobalLayerResources[2] as LnkeResource;
    AssertIsNotNull(lnk2Resource);
    AssertIsNotNull(lnkeResrource);
    AssertAreEqual(1, lnk2Resource.DataSourceCount);
    AssertAreEqual(0, lnkeResrource.DataSourceCount);

    // Replacing of embedded object with linked object
    smartObjectLayer.ReplaceContents(replaceFile);

    // Check Smart layers resources after Smart object replacement
    AssertIsNotNull(smartObjectLayer.Resources[9] as SoLeResource);
    AssertIsNotNull(smartObjectLayer.Resources[10] as FxrpResource);
    AssertAreEqual(0, lnk2Resource.DataSourceCount);
    AssertAreEqual(1, lnkeResrource.DataSourceCount);

    // Embed linked object
    smartObjectLayer.EmbedLinked();

    AssertIsNotNull(smartObjectLayer.Resources[9] as PlLdResource);
    AssertIsNotNull(smartObjectLayer.Resources[10] as SoLdResource);
    AssertIsNotNull(smartObjectLayer.Resources[11] as FxrpResource);
    AssertAreEqual(1, lnk2Resource.DataSourceCount);
    AssertAreEqual(0, lnkeResrource.DataSourceCount);

    psdImage.Save(outputFile, new PsdOptions());

    // Saved psd file should be readable by PS.
}

void AssertAreEqual(object expected, object actual, string message = null)
{
    if (!object.Equals(expected, actual))
    {
        throw new Exception(message ?? "Objects are not equal.");
    }
}

void AssertIsNotNull(object actual)
{
    if (actual == null)
    {
        throw new Exception("Object is null.");
    }
}

PSDNET-2541. [Regression] Fix freeze on export AiImage while parsing of EPSF files

string inputFile = Path.Combine(baseFolder, "[SA]_ID_card_template.ai");
string outputFile = Path.Combine(outputFolder, "output.png");

using (AiImage image = (AiImage)Image.Load(inputFile))
{
    image.Save(outputFile, new PngOptions());

    // Test parsing of PostScript in the epsf file.
}

PSDNET-2543. Missed the Header of AiImage

string inputFile = Path.Combine(baseFolder, "PdfbasedAi.ai");

using (AiImage image = (AiImage)Image.Load(inputFile))
{
    AssertIsNotNull(image.Header);
    AssertAreEqual("PdfbasedAi", image.Header.Title);
    AssertAreEqual("Adobe Illustrator 25.4 (Windows)", image.Header.Creator);
    AssertAreEqual("D:20241218201621+04'00'", image.Header.CreationDate);
}

void AssertAreEqual(object expected, object actual, string message = null)
{
    if (!object.Equals(expected, actual))
    {
        throw new Exception(message ?? "Objects are not equal.");
    }
}

void AssertIsNotNull(object actual)
{
    if (actual == null)
    {
        throw new Exception("Object is null.");
    }
}

PSDNET-2544. Vertically inverted text rendering when exporting from AiImage [NET7.0+]

// This test is for NET7.0 or greater frameworks.
string sourceFile = Path.Combine(baseFolder, "2357_1.ai");
string outputFile = Path.Combine(outputFolder, "2357_1.png");

using (AiImage image = (AiImage)Image.Load(sourceFile))
{
    image.Save(outputFile, new PngOptions());
}