Class SmartObjectResource

SmartObjectResource class

Defines the SmartObjectResource class that contains information about a smart object layer in a PSD file. Is is the base class for Sold and Sole resources that is used to support smart object layers in the Adobe® Photoshop® images.

public abstract class SmartObjectResource : PlacedResource, ISmartObjectLayerResource

Properties

NameDescription
override AntiAliasPolicy { get; set; }Gets or sets the anti alias policy of the smart object layer data in the PSD image.
Bottom { get; set; }Gets or sets the bottom location of the placed layer in the PSD image.
Bounds { get; set; }Gets or sets the bounds of the placed layer in the PSD file.
Comp { get; set; }Gets or sets the comp value of the smart object layer data in the PSD file. Layer comps in Smart Objects
CompId { get; set; }Gets or sets the ID of the currently selected comp for the child document, which will be -1 if none are selected. Comps are compositions of a page layout which designers can create. Using layer comps, you can create, manage, and view multiple versions of a layout in a single Adobe® Photoshop® file. A layer comp is a snapshot of a state of the Layers panel. Layer comps save three types of layer options but this property gets the Layer Comp selection identifier for he smart object layer in the PSD file. Layer comps in Smart Objects
Crop { get; set; }Gets or sets the crop of the smart object layer data in the PSD image.
DurationDenominator { get; set; }Gets or sets the duration denominator.
DurationNumerator { get; set; }Gets or sets the duration numerator.
FrameCount { get; set; }Gets or sets the frame count of the smart object layer data in the PSD file.
FrameStepDenominator { get; set; }Gets or sets the frame step denominator.
FrameStepNumerator { get; set; }Gets or sets the frame step numerator.
Height { get; set; }Gets or sets the height.
HorizontalMeshPoints { get; set; }Gets or sets the horizontal mesh points of the placed layer in the PSD file.
HorizontalMeshPointUnit { get; set; }Gets or sets the measure unit of the horizontal mesh points.
IsCustom { get; set; }Gets or sets a value indicating whether this instance warp style is custom. If true it contains mesh points. If set to false it erases mesh points.
override Items { get; set; }Gets or sets the descriptor items of the smart object layer data in the PSD file.
abstract Key { get; }Gets the layer resource key.
Left { get; set; }Gets or sets the left location of the placed layer in the PSD file.
override Length { get; }Gets the smart object resource length in bytes.
NonAffineTransformMatrix { get; set; }Gets or sets the non affine transform matrix of the smart object layer data in the PSD file.
OriginalCompId { get; }Gets the original ID of the currently selected Comp for the child document, which will be -1 if none are selected. This property gets the original layer Comp selection identifier for he smart object layer in the PSD file. Layer comps in Smart Objects
override PageNumber { get; set; }Gets or sets the page number of the smart object layer data in the PSD file.
Perspective { get; set; }Gets or sets the perspective value of the placed layer in the PSD file.
PerspectiveOther { get; set; }Gets or sets the perspective other value of the placed layer in the PSD file.
PlacedId { get; set; }Gets or sets the unique identifier of this smart object layer data in the PSD image.
override PlacedLayerType { get; set; }Gets or sets the type of the smart object layer data in the PSD file.
override PsdVersion { get; }Gets the minimal psd version required for the smart object resource. 0 indicates no restrictions.
Resolution { get; set; }Gets or sets the resolution of the smart object layer data in the PSD file.
ResolutionUnit { get; set; }Gets or sets the resolution measure unit of the smart object layer data in the PSD file.
Right { get; set; }Gets or sets the right location of the placed layer in the PSD file.
override Signature { get; }Gets the smart object resource signature.
Top { get; set; }Gets or sets the top location of the placed layer in the PSD image.
override TotalPages { get; set; }Gets or sets the total pages number of the smart object layer data in the PSD file.
override TransformMatrix { get; set; }Gets or sets the transform matrix of the smart object layer data in the PSD file.
override UniqueId { get; set; }Gets or sets the global unique identifier of the smart object layer data SmartObjectResource in the PSD image.
UOrder { get; set; }Gets or sets the U order value of the placed layer in the PSD file.
Value { get; set; }Gets or sets the warp value of the placed layer in the PSD image.
Version { get; }Gets the version of the placed layer in the PSD file, usually 3.
VerticalMeshPoints { get; set; }Gets or sets the horizontal mesh points of the placed layer in the PSD file.
VerticalMeshPointUnit { get; set; }Gets or sets the measure unit of the vertical mesh points.
VOrder { get; set; }Gets or sets the V order value of the placed layer in the PSD file.
Width { get; set; }Gets or sets the width.

Methods

NameDescription
override Save(StreamContainer, int)Saves the smart object resource to the specified stream container.
override ToString()Returns a String that represents this instance.

Examples

The following code demonstrates the support of the SoLEResource, SmartObjectResource and PlacedResource resources.

[C#]

void AssertIsTrue(bool condition)
{
    if (!condition)
    {
        throw new FormatException(string.Format("Expected true"));
    }
}

void AssertAreEqual(object actual, object expected)
{
    var areEqual = object.Equals(actual, expected);
    if (!areEqual && actual is Array && expected is Array)
    {
        var actualArray = (Array)actual;
        var expectedArray = (Array)actual;
        if (actualArray.Length == expectedArray.Length)
        {
            for (int i = 0; i < actualArray.Length; i++)
            {
                if (!object.Equals(actualArray.GetValue(i), expectedArray.GetValue(i)))
                {
                    break;
                }
            }

            areEqual = true;
        }
    }

    if (!areEqual)
    {
        throw new FormatException(
            string.Format("Actual value {0} are not equal to expected {1}.", actual, expected));
    }
}

void CheckSmartObjectResourceValues(object[] expectedValue, SmartObjectResource resource)
{
    AssertAreEqual(expectedValue[0], resource.IsCustom);
    AssertAreEqual(expectedValue[2], resource.PageNumber);
    AssertAreEqual(expectedValue[3], resource.TotalPages);
    AssertAreEqual(expectedValue[4], resource.AntiAliasPolicy);
    AssertAreEqual(expectedValue[5], resource.PlacedLayerType);
    AssertAreEqual(8, resource.TransformMatrix.Length);
    AssertAreEqual((double[])expectedValue[6], resource.TransformMatrix);
    AssertAreEqual(expectedValue[7], resource.Value);
    AssertAreEqual(expectedValue[8], resource.Perspective);
    AssertAreEqual(expectedValue[9], resource.PerspectiveOther);
    AssertAreEqual(expectedValue[10], resource.Top);
    AssertAreEqual(expectedValue[11], resource.Left);
    AssertAreEqual(expectedValue[12], resource.Bottom);
    AssertAreEqual(expectedValue[13], resource.Right);
    AssertAreEqual(expectedValue[14], resource.UOrder);
    AssertAreEqual(expectedValue[15], resource.VOrder);

    AssertAreEqual(expectedValue[16], resource.Crop);
    AssertAreEqual(expectedValue[17], resource.FrameStepNumerator);
    AssertAreEqual(expectedValue[18], resource.FrameStepDenominator);
    AssertAreEqual(expectedValue[19], resource.DurationNumerator);
    AssertAreEqual(expectedValue[20], resource.DurationDenominator);
    AssertAreEqual(expectedValue[21], resource.FrameCount);
    AssertAreEqual(expectedValue[22], resource.Width);
    AssertAreEqual(expectedValue[23], resource.Height);
    AssertAreEqual(expectedValue[24], resource.Resolution);
    AssertAreEqual(expectedValue[25], resource.ResolutionUnit);
    AssertAreEqual(expectedValue[26], resource.Comp);
    AssertAreEqual(expectedValue[27], resource.CompId);
    AssertAreEqual(expectedValue[28], resource.OriginalCompId);
    AssertAreEqual(expectedValue[29], resource.PlacedId.ToString());
    AssertAreEqual(expectedValue[30], resource.NonAffineTransformMatrix);
    if (resource.IsCustom)
    {
        AssertAreEqual(expectedValue[31], resource.HorizontalMeshPointUnit);
        AssertAreEqual((double[])expectedValue[32], resource.HorizontalMeshPoints);
        AssertAreEqual(expectedValue[33], resource.VerticalMeshPointUnit);
        AssertAreEqual((double[])expectedValue[34], resource.VerticalMeshPoints);
    }
}

void SetNewSmartValues(SmartObjectResource resource, object[] newValues)
{
    // This values we do not change in resource
    newValues[0] = resource.IsCustom;
    newValues[1] = resource.UniqueId.ToString();
    newValues[5] = resource.PlacedLayerType;
    newValues[14] = resource.UOrder;
    newValues[15] = resource.VOrder;
    newValues[28] = resource.OriginalCompId;

    // This values should be changed in the PlLdResource (with the specified UniqueId) as well
    // and some of them must be in accord with the underlining smart object in the LinkDataSource
    resource.PageNumber = (int)newValues[2]; // 2;
    resource.TotalPages = (int)newValues[3]; // 3;
    resource.AntiAliasPolicy = (int)newValues[4]; // 0;
    resource.TransformMatrix = (double[])newValues[6];
    resource.Value = (double)newValues[7]; // 1.23456789;
    resource.Perspective = (double)newValues[8]; // 0.123456789;
    resource.PerspectiveOther = (double)newValues[9]; // 0.987654321;
    resource.Top = (double)newValues[10]; // -126;
    resource.Left = (double)newValues[11]; // -215;
    resource.Bottom = (double)newValues[12]; // 248;
    resource.Right = (double)newValues[13]; // 145;
    resource.Crop = (int)newValues[16]; // 5;
    resource.FrameStepNumerator = (int)newValues[17]; // 1;
    resource.FrameStepDenominator = (int)newValues[18]; // 601;
    resource.DurationNumerator = (int)newValues[19]; // 2;
    resource.DurationDenominator = (int)newValues[20]; // 602;
    resource.FrameCount = (int)newValues[21]; // 11;
    resource.Width = (double)newValues[22]; // 541;
    resource.Height = (double)newValues[23]; // 249;
    resource.Resolution = (double)newValues[24]; // 144;
    resource.ResolutionUnit = (UnitTypes)newValues[25];
    resource.Comp = (int)newValues[26]; // 21;
    resource.CompId = (int)newValues[27]; // 22;
    resource.NonAffineTransformMatrix = (double[])newValues[30];

    // This unique Id should be changed in references if any
    resource.PlacedId = new Guid((string)newValues[29]);  // "12345678-9abc-def0-9876-54321fecba98");
    if (resource.IsCustom)
    {
        resource.HorizontalMeshPointUnit = (UnitTypes)newValues[31];
        resource.HorizontalMeshPoints = (double[])newValues[32];
        resource.VerticalMeshPointUnit = (UnitTypes)newValues[33];
        resource.VerticalMeshPoints = (double[])newValues[34];
    }

    // Be careful with some parameters: the saved image may become unreadable by Adobe® Photoshop®
    ////resource.UOrder = 6;
    ////resource.VOrder = 9;

    // Do no change this otherwise you won't be able to use free transform
    // or change the underlining smart object to the vector type
    ////resource.PlacedLayerType = PlacedLayerType.Vector;

    // There should be valid PlLdResource with this unique Id
    ////resource.UniqueId = new Guid("98765432-10fe-cba0-1234-56789abcdef0");
}

object[] newSmartValues = new object[]
{
    true,
    null,
    2,
    3,
    0,
    PlacedLayerType.ImageStack,
    new double[8]
    {
        12.937922786050663,
        19.419959734187131,
        2.85445817782261,
        1.0540625423957124,
        7.20861031651307,
        14.634102808208553,
        17.292074924741144,
        4
    },
    1.23456789,
    0.123456789,
    0.987654321,
    -126d,
    -215d,
    248d,
    145d,
    4,
    4,
    5,
    1,
    601,
    2,
    602,
    11,
    541d,
    249d,
    144d,
    UnitTypes.Percent,
    21,
    22,
    23,
    "12345678-9abc-def0-9876-54321fecba98",
    new double[8]
    {
        129.937922786050663,
        195.419959734187131,
        26.85445817782261,
        12.0540625423957124,
        72.20861031651307,
        147.634102808208553,
        175.292074924741144,
        42
    },
    UnitTypes.Points,
    new double[16]
    {
        0.01d, 103.33333333333433d, 206.66686666666666d, 310.02d,
        0.20d, 103.33333333333533d, 206.69666666666666d, 310.03d,
        30.06d, 103.33333333336333d, 206.66660666666666d, 310.04d,
        04.05d, 103.33333333373333d, 206.66666166666666d, 310.05d
    },
    UnitTypes.Distance,
    new double[16]
    {
        0.06d, 0.07d, 0.08d, 0.09d,
        49.066666666666664d, 49.266666666666664d, 49.566666666666664d, 49.766666666666664d,
        99.133333333333329d, 99.433333333333329d, 99.633333333333329d, 99.833333333333329d,
        140, 141, 142, 143,
    },
};

object[] expectedValues = new object[]
{
    new object[]
    {
        false,
        "5867318f-3174-9f41-abca-22f56a75247e",
        1,
        1,
        0x10,
        PlacedLayerType.Raster,
        new double[8]
        {
            0, 0, 2, 0, 2, 2, 0, 2
        },
        0d,
        0d,
        0d,
        0d,
        0d,
        2d,
        2d,
        4,
        4,
        1,
        0,
        600,
        0,
        600,
        1,
        2d,
        2d,
        72d,
        UnitTypes.Density,
        -1,
        -1,
        -1,
        "64b3997c-06e0-be40-a349-41acf397c897",
        new double[8]
        {
            0, 0, 2, 0, 2, 2, 0, 2
        },
    }
};

var sourceFilePath = "rgb8_2x2_linked.psd";
var outputPath = "rgb8_2x2_linked_output.psd";
using (PsdImage image = (PsdImage)Image.Load(sourceFilePath))
{
    SoLeResource soleResource = null;
    int index = 0;
    foreach (Layer imageLayer in image.Layers)
    {
        foreach (var imageResource in imageLayer.Resources)
        {
            var resource = imageResource as SoLeResource;
            if (resource != null)
            {
                soleResource = resource;
                var expectedValue = (object[])expectedValues[index++];
                AssertAreEqual(expectedValue[1], resource.UniqueId.ToString());
                CheckSmartObjectResourceValues(expectedValue, resource);
                SetNewSmartValues(resource, newSmartValues);

                break;
            }
        }
    }

    AssertIsTrue(soleResource != null);
    image.Save(outputPath, new PsdOptions(image));
    using (PsdImage savedImage = (PsdImage)Image.Load(outputPath))
    {
        foreach (Layer imageLayer in savedImage.Layers)
        {
            foreach (var imageResource in imageLayer.Resources)
            {
                var resource = imageResource as SoLeResource;
                if (resource != null)
                {
                    CheckSmartObjectResourceValues(newSmartValues, resource);

                    break;
                }
            }
        }
    }
}

See Also