Aspose.PSD for .NET 18.8 - Release Notes
| Key | Summary | Category | 
|---|---|---|
| PSDNET-68 | Support of the LayerCreationDateTime property. | Feature | 
| PSDNET-67 | Support of the SheetColor Highlighting | Feature | 
| PSDNET-66 | Ability to merge layers one to another | Feature | 
| PSDNET-65 | Add partial support of the Text Layer BoundBox property | Feature | 
| PSDNET-64 | Add support for IopaResource | Feature | 
| PSDNET-56 | Support Layer Effects for PSD format | Feature | 
| PSDNET-55 | InterruptMonitor support for .Net | Feature | 
| PSDNET-50 | Make possibility to flatten layers | Feature | 
| PSDNET-49 | Add the rendering of the fill opacity property in layers. | Feature | 
| PSDNET-43 | Implement rendering of Curves Adjustment Layer | Feature | 
| PSDNET-42 | Add support of Curves Adjustment Layer | Feature | 
| PSDNET-41 | Implement rendering of Levels Adjustment Layer | Feature | 
| PSDNET-40 | Add support of the Levels adjustment Layer | Feature | 
| PSDNET-37 | Add support of Channel Mixer Adjustment Layer | Feature | 
| PSDNET-35 | Add support of Hue/Saturation Adjustment Layer | Feature | 
| PSDNET-34 | Implement Exposure Adjustment Layer rendering for export. | Feature | 
| PSDNET-31 | Add support of rendering for export of ChannelMixer adjusment layer | Feature | 
| PSDNET-26 | Add support of Clipping mask | Feature | 
| PSDNET-13 | Add support of the layer mask | Feature | 
| PSDNET-9 | Add support of Photo Filter adjustment layer | Feature | 
| PSDNET-8 | Add support of Channel mixer adjusment layer | Feature | 
| PSDNET-7 | Add support of Exposure adjustment layer | Feature | 
| PSDNET-6 | Add support of Brightness/Contrast adjustment layer | Feature | 
| PSDNET-5 | Add partially support of adjustments layers | Feature | 
| PSDNET-3 | Add support for PSD NoBreak text option | Feature | 
| PSDNET-2 | Ability to add Text Layer in run-time | Feature | 
| PSDNET-62 | TIFF Codec can’t save 16-bit channel image | Enhancement | 
| PSDNET-61 | Saving of PSD image produces invalid image colors | Enhancement | 
| PSDNET-60 | Coordinate of left top corner is incorrect at update | Enhancement | 
| PSDNET-59 | Exception on updating text layers | Enhancement | 
| PSDNET-58 | Expose Codec property of JPEG2000 image to public | Enhancement | 
| PSDNET-57 | Fix 24bpp options setting for export to BMP | Enhancement | 
| PSDNET-46 | Adjustment layer ignored for CMYK PSD conversion to TIFF or JPG | Enhancement | 
Usage examples:
PSDNET-68 Support of the LayerCreationDateTime property
 // Example of LayerCreationDateTime property using
string sourceFileName = "OneLayer.psd";
using (var im = (PsdImage)(Image.Load(sourceFileName)))
{
    var layer = im.Layers[0];
    var creationDateTime = layer.LayerCreationDateTime;
    var expectedDateTime = new DateTime(2018, 7, 17, 8, 57, 24, 769);
    Assert.AreEqual(expectedDateTime, creationDateTime);
    var now = DateTime.Now;
    var createdLayer = im.AddLevelsAdjustmentLayer();
    // Check if Creation Date Time Updated on newly created layers
    Assert.True(now <= createdLayer.LayerCreationDateTime);
}PSDNET-67 Support of the SheetColor Highlighting
 // Using example of the SheetColorHighlight property
string sourceFileName = "SheetColorHighlightExample.psd";
string exportPath = "SheetColorHighlightExampleChanged.psd";
using (var im = (PsdImage)(Image.Load(sourceFileName)))
{
    var layer1 = im.Layers[0];
    Assert.AreEqual(SheetColorHighlightEnum.Violet, layer1.SheetColorHighlight);
    var layer2 = im.Layers[1];
    Assert.AreEqual(SheetColorHighlightEnum.Orange, layer2.SheetColorHighlight);
    layer1.SheetColorHighlight = SheetColorHighlightEnum.Yellow;
    im.Save(exportPath);	
}PSDNET-66 Ability to merge layers one to another
 // Merging two layers example
var sourceFile1 = "FillOpacitySample.psd";
var sourceFile2 = "ThreeRegularLayersSemiTransparent.psd";
var exportPath = "MergedLayersFromTwoDifferentPsd.psd" 
using (var im1 = (PsdImage)(Image.Load(sourceFile1)))
{
    var layer1 = im1.Layers[1];
    using (var im2 = (PsdImage)(Image.Load(sourceFile2)))
    {
        var layer2 = im2.Layers[0];
        layer1.MergeLayerTo(layer2);
	im2.Save(exportPath);	
    }
}PSDNET-65 Add partial support of the Text Layer BoundBox property
 // Text BoxBounds Example
string sourceFileName = "LayerWithText.psd";
var correctOpticalSize = new Size(127, 45);
var correctBoundBox = new Size(172, 62);
using (var im = (PsdImage)(Image.Load(sourceFileName)))
{
    var textLayer = (TextLayer)im.Layers[1];
    // Size of the layer is the size of the rendered area
    var opticalSize = textLayer.Size;
    Assert.AreEqual(correctOpticalSize, opticalSize);
    // TextBoundBox is the maximum layer size for Text Layer. 
    // In this area PS will try to fit your text
    var boundBox = textLayer.TextBoundBox;
    Assert.AreEqual(correctBoundBox, boundBox);
}PSDNET-64 Add support for IopaResource
 // Change the Fill Opacity property by the IopaResource change
string sourceFileName = "FillOpacitySample.psd";
string exportPath = "FillOpacitySampleChanged.psd";
using (var im = (PsdImage)(Image.Load(sourceFileName)))
{
    var layer = im.Layers[2];
    var resources = layer.Resources;
    foreach (var resource in resources)
    {
        if (resource is IopaResource)
        {
            var iopaResource = (IopaResource)resource;
            iopaResource.FillOpacity = 200;
        }
    }
    im.Save(exportPath);	
}PSDNET-56 Support Layer Effects for PSD format
 using (
    PsdImage image =
        (PsdImage)
        Aspose.PSD.Image.Load(
            sourceFileName,
            new Aspose.PSD.ImageLoadOptions.PsdLoadOptions()
            {
                LoadEffectsResource = true,
                UseDiskForLoadEffectsResource = true
            }))
{
    image.Save(
                output,
                new Aspose.PSD.ImageOptions.PngOptions()
                {
                    ColorType =
                            Aspose.PSD.FileFormats.Png
                            .PngColorType
                            .TruecolorWithAlpha
                });
}PSDNET-55 InterruptMonitor support for .Net
         public void InterruptMonitorTest(string dir, string ouputDir)
        {
            ImageOptionsBase saveOptions = new ImageOptions.PngOptions();
            Multithreading.InterruptMonitor monitor = new Multithreading.InterruptMonitor();
            SaveImageWorker worker = new SaveImageWorker(dir + "big.psb", dir + "big_out.png", saveOptions, monitor);
            System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(worker.ThreadProc));
            try
            {
                thread.Start();
                // The timeout should be less than the time required for full image conversion (without interruption).
                System.Threading.Thread.Sleep(3000);
                // Interrupt the process
                monitor.Interrupt();
                System.Console.WriteLine("Interrupting the save thread #{0} at {1}", thread.ManagedThreadId, System.DateTime.Now);
                // Wait for interruption...
                thread.Join();
            }
            finally
            {
                // If the file to be deleted does not exist, no exception is thrown.
                System.IO.File.Delete(dir + "big_out.png");
            }
        }
        /// <summary>
        /// Initiates image conversion and waits for its interruption.
        /// </summary>
        private class SaveImageWorker
        {
            /// <summary>
            /// The path to the input image.
            /// </summary>
            private readonly string inputPath;
            /// <summary>
            /// The path to the output image.
            /// </summary>
            private readonly string outputPath;
            /// <summary>
            /// The interrupt monitor.
            /// </summary>
            private readonly Multithreading.InterruptMonitor monitor;
            /// <summary>
            /// The save options.
            /// </summary>
            private readonly ImageOptionsBase saveOptions;
            /// <summary>
            /// Initializes a new instance of the <see cref="SaveImageWorker" /> class.
            /// </summary>
            /// <param name="inputPath">The path to the input image.</param>
            /// <param name="outputPath">The path to the output image.</param>
            /// <param name="saveOptions">The save options.</param>
            /// <param name="monitor">The interrupt monitor.</param>
            public SaveImageWorker(string inputPath, string outputPath, ImageOptionsBase saveOptions, Multithreading.InterruptMonitor monitor)
            {
                this.inputPath = inputPath;
                this.outputPath = outputPath;
                this.saveOptions = saveOptions;
                this.monitor = monitor;
            }
            /// <summary>
            /// Tries to convert image from one format to another. Handles interruption. 
            /// </summary>
            public void ThreadProc()
            {
                using (Image image = Image.Load(this.inputPath))
                {
                    Multithreading.InterruptMonitor.ThreadLocalInstance = this.monitor;
                    try
                    {
                        image.Save(this.outputPath, this.saveOptions);
                        Assert.Fail("Expected interruption.");
                    }
                    catch (CoreExceptions.OperationInterruptedException e)
                    {
                        System.Console.WriteLine("The save thread #{0} finishes at {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, System.DateTime.Now);
                        System.Console.WriteLine(e);
                    }
                    catch (System.Exception e)
                    {
                        System.Console.WriteLine(e);
                    }
                    finally
                    {
                        Multithreading.InterruptMonitor.ThreadLocalInstance = null;
                    }
                }
            }
        }PSDNET-50 Make possibility to flatten layers
 // Flatten whole PSD
string sourceFileName = "ThreeRegularLayersSemiTransparent.psd";
string exportPath = "ThreeRegularLayersSemiTransparentFlattened.psd";
using (var im = (PsdImage)(Image.Load(sourceFileName)))
{
    im.FlattenImage();
    im.Save(exportPath);	 
}
// Merge one layer in another
string sourceFileName = "ThreeRegularLayersSemiTransparent.psd";
string exportPath = "ThreeRegularLayersSemiTransparentFlattenedLayerByLayer.psd";
using (var im = (PsdImage)(Image.Load(sourceFileName)))
{
    var bottomLayer = im.Layers[0];
    var middleLayer = im.Layers[1];
    var topLayer = im.Layers[2];
    var layer1 = im.MergeLayers(bottomLayer, middleLayer);
    var layer2 = im.MergeLayers(layer1, topLayer);
    // Set up merged layers
    im.Layers = new Layer[] { layer2 };
    im.Save(exportPath);	 
}PSDNET-49 Add the rendering of the fill opacity property in layers.
 // Change the Fill Opacity property
string sourceFileName = "FillOpacitySample.psd";
string exportPath = "FillOpacitySampleChanged.psd";
using (var im = (PsdImage)(Image.Load(sourceFileName)))
{
    var layer = im.Layers[2];
    layer.FillOpacity = 5;
    im.Save(exportPath);	
}PSDNET-43 Implement rendering of Curves Adjustment Layer
 // Curves layer editing
string sourceFileName = "CurvesAdjustmentLayer";
string psdPathAfterChange = "CurvesAdjustmentLayerChanged";
string pngExportPath = "CurvesAdjustmentLayerChanged";
for (int j = 1; j < 2; j++)
{
    using (var im = LoadFile(sourceFileName + j.ToString() + ".psd"))
    {
        foreach (var layer in im.Layers)
	{
            if (layer is CurvesLayer)
            {
                 var curvesLayer = (CurvesLayer)layer;
                 if (curvesLayer.IsDiscreteManagerUsed)
                 {
                      var manager = (CurvesDiscreteManager)curvesLayer.GetCurvesManager();
                      for (int i = 10; i < 50; i++)
                      {
                           manager.SetValueInPosition(0, (byte)i, (byte)(15 + (i * 2)));
                      }
                 }
                 else
                 {
                      var manager = (CurvesContinuousManager)curvesLayer.GetCurvesManager();
                      manager.AddCurvePoint(0, 50, 100);
                      manager.AddCurvePoint(0, 150, 130);
                 }
            }
        }
    }
    // Save PSD
    im.Save(psdPathAfterChange + j.ToString() + ".psd");
    // Save PNG
    var saveOptions = new PngOptions();
    saveOptions.ColorType = PngColorType.TruecolorWithAlpha;
    im.Save(pngExportPath + j.ToString() + ".png", saveOptions);
}PSDNET-42 Add support of Curves Adjustment Layer
 // Curves layer editing
string sourceFileName = "CurvesAdjustmentLayer";
string psdPathAfterChange = "CurvesAdjustmentLayerChanged";
for (int j = 1; j < 2; j++)
{
    using (var im = LoadFile(sourceFileName + j.ToString() + ".psd"))
    {
         foreach (var layer in im.Layers)
	 {
            if (layer is CurvesLayer)
            {
                 var curvesLayer = (CurvesLayer)layer;
                 if (curvesLayer.IsDiscreteManagerUsed)
                 {
                      var manager = (CurvesDiscreteManager)curvesLayer.GetCurvesManager();
                      for (int i = 10; i < 50; i++)
                      {
                           manager.SetValueInPosition(0, (byte)i, (byte)(15 + (i * 2)));
                      }
                 }
                 else
                 {
                      var manager = (CurvesContinuousManager)curvesLayer.GetCurvesManager();
                      manager.AddCurvePoint(0, 50, 100);
                      manager.AddCurvePoint(0, 150, 130);
                 }
            }
	}
    }
    // Save PSD
    im.Save(psdPathAfterChange + j.ToString() + ".psd");
}PSDNET-41 Implement rendering of Levels Adjustment Layer
 // Levels layer editing
string sourceFileName = "LevelsAdjustmentLayer.psd";
string psdPathAfterChange = "LevelsAdjustmentLayerChanged.psd";
string pngExportPath = "LevelsAdjustmentLayerChanged.png";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
        if (layer is LevelsLayer)
        {
            var levelsLayer = (LevelsLayer)layer;
            var channel = levelsLayer.GetChannel(0);
            channel.InputMidtoneLevel = 2.0f;
            channel.InputShadowLevel = 10;
            channel.InputHighlightLevel = 230;
            channel.OutputShadowLevel = 20;
            channel.OutputHighlightLevel = 200;
        }
    }
    // Save PSD
    im.Save(psdPathAfterChange);
    // Save PNG
    var saveOptions = new PngOptions();
    saveOptions.ColorType = PngColorType.TruecolorWithAlpha;
    im.Save(pngExportPath, saveOptions);
}PSDNET-40 Add support of the Levels adjustment Layer
 // Levels layer editing
string sourceFileName = "LevelsAdjustmentLayer.psd";
string psdPathAfterChange = "LevelsAdjustmentLayerChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
        if (layer is LevelsLayer)
        {
            var levelsLayer = (LevelsLayer)layer;
            var channel = levelsLayer.GetChannel(0);
            channel.InputMidtoneLevel = 2.0f;
            channel.InputShadowLevel = 10;
            channel.InputHighlightLevel = 230;
            channel.OutputShadowLevel = 20;
            channel.OutputHighlightLevel = 200;
        }
    }
    // Save PSD
    im.Save(psdPathAfterChange);
}PSDNET-37 Add support of Channel Mixer Adjustment Layer
// Rgb Channel Mixer
string sourceFileName = "ChannelMixerAdjustmentLayerRgb.psd";
string psdPathAfterChange = "ChannelMixerAdjustmentLayerRgbChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
         if (layer is RgbChannelMixerLayer)
         {
              var rgbLayer = (RgbChannelMixerLayer)layer;
              rgbLayer.RedChannel.Blue = 100;
              rgbLayer.BlueChannel.Green = -100;
              rgbLayer.GreenChannel.Constant = 50;
         }
    }
    im.Save(psdPathAfterChange);
}
// Cmyk Channel Mixer
string sourceFileName = "ChannelMixerAdjustmentLayerCmyk.psd";
string psdPathAfterChange = "ChannelMixerAdjustmentLayerCmykChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
         if (layer is CmykChannelMixerLayer)
         {
             var cmykLayer = (CmykChannelMixerLayer)layer;
             cmykLayer.CyanChannel.Black = 20;
             cmykLayer.MagentaChannel.Yellow = 50;
             cmykLayer.YellowChannel.Cyan = -25;
             cmykLayer.BlackChannel.Yellow = 25;
         }
    }
    im.Save(psdPathAfterChange);
}
// Adding the new layer(Cmyk for this example)
string sourceFileName = "CmykWithAlpha.psd";
string psdPathAfterChange = "ChannelMixerAdjustmentLayerCmykChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    var newlayer = im.AddChannelMixerAdjustmentLayer();
    newlayer.GetChannelByIndex(2).Constant = 50;
    newlayer.GetChannelByIndex(0).Constant = 50;
    im.Save(psdPathAfterChange);
}		PSDNET-35 Add support of Hue/Saturation Adjustment Layer
 // Hue/Saturation layer editing
string sourceFileName = "HueSaturationAdjustmentLayer.psd";
string psdPathAfterChange = "HueSaturationAdjustmentLayerChanged.psd";
using (var im = LoadFile(sourceFileName))
{
     foreach (var layer in im.Layers)
     {
           if (layer is HueSaturationLayer)
           {
                var hueLayer = (HueSaturationLayer)layer;
                hueLayer.Hue = -25;
                hueLayer.Saturation = -12;
                hueLayer.Lightness = 67;
                var colorRange = hueLayer.GetRange(2);
                colorRange.Hue = -40;
                colorRange.Saturation = 50;
                colorRange.Lightness = -20;
                colorRange.MostLeftBorder = 300;
           }
      }
      im.Save(psdPathAfterChange);
}
// Hue/Saturation layer adding
string sourceFileName = "PhotoExample.psd";
string psdPathAfterChange = "PhotoExampleAddedHueSaturation.psd";
using (PsdImage im = LoadFile(sourceFileName))
{
     this.SaveForVisualTest(im, this.OutputPath, prefix + file, "before");
     var hueLayer = im.AddHueSaturationAdjustmentLayer();
     hueLayer.Hue = -25;
     hueLayer.Saturation = -12;
     hueLayer.Lightness = 67;
     var colorRange = hueLayer.GetRange(2);
     colorRange.Hue = -160;
     colorRange.Saturation = 100;
     colorRange.Lightness = 20;
     colorRange.MostLeftBorder = 300;
     im.Save(psdPathAfterChange);
}PSDNET-34 Implement Exposure Adjustment Layer rendering for export.
 // Exposure layer editing
string sourceFileName = "ExposureAdjustmentLayer.psd";
string psdPathAfterChange = "ExposureAdjustmentLayerChanged.psd";
string pngExportPath = "ExposureAdjustmentLayerChanged.png";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
        if (layer is ExposureLayer)
        {
	    var expLayer = (ExposureLayer)layer;
            expLayer.Exposure = 2;
            expLayer.Offset = -0.25f;
            expLayer.GammaCorrection = 0.5f;
        }
    }
    // Save PSD
    im.Save(psdPathAfterChange);
    // Save PNG
    var saveOptions = new PngOptions();
    saveOptions.ColorType = PngColorType.TruecolorWithAlpha;
    im.Save(pngExportPath, saveOptions);
}
// Exposure layer adding
string sourceFileName = "PhotoExample.psd";
string psdPathAfterChange = "PhotoExampleAddedExposure.psd";
string pngExportPath = "PhotoExampleAddedExposure.png";
using (PsdImage im = LoadFile(sourceFileName))
{
     var newlayer = im.AddExposureAdjustmentLayer();
     newlayer.Exposure = 2;
     newlayer.Offset = -0.25f;
     newlayer.GammaCorrection = 2f;
     // Save PSD
     im.Save(psdPathAfterChange);
     // Save PNG
     var saveOptions = new PngOptions();
     saveOptions.ColorType = PngColorType.TruecolorWithAlpha;
     im.Save(pngExportPath, saveOptions);
}PSDNET-31 Add support of rendering for export of ChannelMixer adjusment layer
// Rgb Channel Mixer
string sourceFileName = "ChannelMixerAdjustmentLayerRgb.psd";
string psdPathAfterChange = "ChannelMixerAdjustmentLayerRgbChanged.psd";
string pngExportPath = "ChannelMixerAdjustmentLayerRgbChanged.png";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
         if (layer is RgbChannelMixerLayer)
         {
              var rgbLayer = (RgbChannelMixerLayer)layer;
              rgbLayer.RedChannel.Blue = 100;
              rgbLayer.BlueChannel.Green = -100;
              rgbLayer.GreenChannel.Constant = 50;
         }
    }
	// Save PSD
    im.Save(psdPathAfterChange);
	// Save PNG
    var saveOptions = new PngOptions();
    saveOptions.ColorType = PngColorType.TruecolorWithAlpha;
    im.Save(pngExportPath, saveOptions);
}
// Cmyk Channel Mixer
string sourceFileName = "ChannelMixerAdjustmentLayerCmyk.psd";
string psdPathAfterChange = "ChannelMixerAdjustmentLayerCmykChanged.psd";
string pngExportPath = "ChannelMixerAdjustmentLayerCmykChanged.png";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
         if (layer is CmykChannelMixerLayer)
         {
             var cmykLayer = (CmykChannelMixerLayer)layer;
             cmykLayer.CyanChannel.Black = 20;
             cmykLayer.MagentaChannel.Yellow = 50;
             cmykLayer.YellowChannel.Cyan = -25;
             cmykLayer.BlackChannel.Yellow = 25;
         }
    }
	// Save PSD
    im.Save(psdPathAfterChange);
	// Save PNG
    var saveOptions = new PngOptions();
    saveOptions.ColorType = PngColorType.TruecolorWithAlpha;
    im.Save(pngExportPath, saveOptions);
}PSDNET-26 Add support of Clipping mask
 // Export of the psd with complex clipping mask
string sourceFileName = "ClippingMaskComplex.psd";
string exportPath = "ClippingMaskComplex.png";
using (var im = LoadFile(sourceFileName))
{
     // Export to PNG
     var saveOptions = new PngOptions();
     saveOptions.ColorType = PngColorType.TruecolorWithAlpha;
     im.Save(exportPath, saveOptions);
}PSDNET-13 Add support of the layer mask
 // Export of the psd with complex mask
string sourceFileName = "MaskComplex.psd";
string exportPath = "MaskComplex.png";
using (var im = LoadFile(sourceFileName))
{
     // Export to PNG
     var saveOptions = new PngOptions();
     saveOptions.ColorType = PngColorType.TruecolorWithAlpha;
     im.Save(exportPath, saveOptions);
}PSDNET-9 Add support of Photo Filter adjustment layer
 // Photo Filter layer editing
string sourceFileName = "PhotoFilterAdjustmentLayer.psd";
string psdPathAfterChange = "PhotoFilterAdjustmentLayerChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
	if (layer is PhotoFilterLayer)
        {
	    var photoLayer = (PhotoFilterLayer)layer;
            photoLayer.Color = Color.FromArgb(255, 60, 60);
            photoLayer.Density = 78;
            photoLayer.PreserveLuminosity = false;
        }
    }
    im.Save(psdPathAfterChange);
}
// Photo Filter layer adding
string sourceFileName = "PhotoExample.psd";
string psdPathAfterChange = "PhotoExampleAddedPhotoFilter.psd";
using (PsdImage im = LoadFile(sourceFileName))
{
    var layer = im.AddPhotoFilterLayer(Color.FromArgb(25, 255, 35));
    im.Save(psdPathAfterChange);
}PSDNET-8 Add support of Channel mixer adjusment layer
// Rgb Channel Mixer
string sourceFileName = "ChannelMixerAdjustmentLayerRgb.psd";
string psdPathAfterChange = "ChannelMixerAdjustmentLayerRgbChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
         if (layer is RgbChannelMixerLayer)
         {
              var rgbLayer = (RgbChannelMixerLayer)layer;
              rgbLayer.RedChannel.Blue = 100;
              rgbLayer.BlueChannel.Green = -100;
              rgbLayer.GreenChannel.Constant = 50;
         }
    }
    im.Save(psdPathAfterChange);
}
// Adding the new layer(Cmyk for this example)
string sourceFileName = "CmykWithAlpha.psd";
string psdPathAfterChange = "ChannelMixerAdjustmentLayerCmykChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    var newlayer = im.AddChannelMixerAdjustmentLayer();
    newlayer.GetChannelByIndex(2).Constant = 50;
    newlayer.GetChannelByIndex(0).Constant = 50;
    im.Save(psdPathAfterChange);
}		PSDNET-7 Add support of Exposure adjustment layer
 // Exposure layer editing
string sourceFileName = "ExposureAdjustmentLayer.psd";
string psdPathAfterChange = "ExposureAdjustmentLayerChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
	if (layer is ExposureLayer)
        {
	    var expLayer = (ExposureLayer)layer;
            expLayer.Exposure = 2;
            expLayer.Offset = -0.25f;
            expLayer.GammaCorrection = 0.5f;
        }
    }
    im.Save(psdPathAfterChange);
}
// Exposure layer adding
string sourceFileName = "PhotoExample.psd";
string psdPathAfterChange = "PhotoExampleAddedExposure.psd";
using (PsdImage im = LoadFile(sourceFileName))
{
     var newlayer = im.AddExposureAdjustmentLayer();
     newlayer.Exposure = 10;
     newlayer.Offset = -0.25f;
     newlayer.GammaCorrection = 2f;
     im.Save(psdPathAfterChange);
}PSDNET-6 Add support of Brightness/Contrast adjusment layer
 // Brightness/Contrast layer editing
string sourceFileName = "BrightnessContrastModern.psd";
string psdPathAfterChange = "BrightnessContrastModernChanged.psd";
using (var im = LoadFile(sourceFileName))
{
    foreach (var layer in im.Layers)
    {
	if (layer is BrightnessContrastLayer)
        {
            var brightnessContrastLayer = (BrightnessContrastLayer)layer;
            brightnessContrastLayer.Brightness = 50;
            brightnessContrastLayer.Contrast = 50;
        }
    }
    // Save PSD
    im.Save(psdPathAfterChange);
}PSDNET-5 Add partially support of adjustments layers
 // Channel Mixer Adjustment Layer
string sourceFileName1 = "ChannelMixerAdjustmentLayer.psd";
string exportPath1 = "ChannelMixerAdjustmentLayerChanged.psd";
using (var im = (PsdImage)(Image.Load(sourceFileName1)))
{
    for (int i = 0; i < im.Layers.Length; i++)
    {
        var adjustmentLayer = im.Layers[i] as AdjustmentLayer;
        if (adjustmentLayer != null)
        {
            adjustmentLayer.MergeLayerTo(im.Layers[0]);
        }
    }
	// Save PSD
    im.Save(exportPath1);
}
// Levels adjustment layer
string sourceFileName2 = "LevelsAdjustmentLayerRgb.psd";
string exportPath2 = "LevelsAdjustmentLayerRgbChanged.psd";
using (var im = (PsdImage)(Image.Load(sourceFileName2)))
{
    for (int i = 0; i < im.Layers.Length; i++)
    {
        var adjustmentLayer = im.Layers[i] as AdjustmentLayer;
        if (adjustmentLayer != null)
        {
            adjustmentLayer.MergeLayerTo(im.Layers[0]);
        }
    }
	// Save PSD
    im.Save(exportPath2);
}PSDNET-2 Ability to add Text Layer in runtime
             string sourceFileName = "OneLayer.psd";
            string psdPath = "ImageWithTextLayer.psd";
            using (var img = Image.Load(sourceFileName))
            {
                PsdImage im = (PsdImage)img;
                var rect = new Rectangle(
                    (int)(im.Width * 0.25),
                    (int)(im.Height * 0.25),
                    (int)(im.Width * 0.5),
                    (int)(im.Height * 0.5));
                var layer = im.AddTextLayer("Added text", rect);
                im.Save(psdPath);
            }PSDNET-62 TIFF Codec can’t save 16-bit channel image
 TiffCompressions[] compressions = new TiffCompressions[] { TiffCompressions.Lzw, TiffCompressions.Deflate };
            TiffByteOrder[] byteOrders = new TiffByteOrder[] { TiffByteOrder.BigEndian, TiffByteOrder.LittleEndian };
            TiffPhotometrics[] photometrics = new TiffPhotometrics[] { TiffPhotometrics.MinIsBlack, TiffPhotometrics.MinIsWhite, TiffPhotometrics.Rgb };
            TiffPlanarConfigs[] planarConfigs = new TiffPlanarConfigs[] { TiffPlanarConfigs.Contiguous, TiffPlanarConfigs.Separate };
            for (int compr = 0; compr < compressions.Length; ++compr)
            {
                TiffCompressions compression = compressions[compr];
                for (int bo = 0; bo < byteOrders.Length; ++bo)
                {
                    TiffByteOrder byteOrder = byteOrders[bo];
                    for (int ph = 0; ph < photometrics.Length; ++ph)
                    {
                        TiffPhotometrics photometric = photometrics[ph];
                        for (int pcfg = 0; pcfg < planarConfigs.Length; ++pcfg)
                        {
                            TiffPlanarConfigs planarConfig = planarConfigs[pcfg];
                            TiffOptions options = new TiffOptions(TiffExpectedFormat.Default, byteOrder);
                            options.Compression = compression;
                            options.Photometric = photometric;
                            options.PlanarConfiguration = planarConfig;
                            switch (photometric)
                            {
                                case TiffPhotometrics.MinIsBlack:
                                case TiffPhotometrics.MinIsWhite:
                                    // No extra samples are used, so alpha is supposed to be unspecified.
                                    options.BitsPerSample = new ushort[] { 16 }; // Grayscale 
                                    break;
                                case TiffPhotometrics.Rgb:
                                case TiffPhotometrics.Ycbcr:
                                    // No extra samples are used, so alpha is supposed to be unspecified.
                                    options.BitsPerSample = new ushort[] { 16, 16, 16 };
                                    break;
                                case TiffPhotometrics.Separated:
                                    // No extra samples are used, so alpha is supposed to be unspecified.
                                    options.BitsPerSample = new ushort[] { 16, 16, 16, 16 }; // CMYK
                                    break;
                                default:
                                    throw new NotSupportedException("The " + photometric + " photometric is not supported at the moment.");
                            }
                            // Horizontal differencing prediction is recommended to use with LZW compression because LZW is probably
                            // the only TIFF encoding scheme that benefits significantly from a predictor step.
                            if (compression == TiffCompressions.Lzw)
                            {
                                options.Predictor = TiffPredictor.Horizontal;
                            }
                            // Use PNG image with alpha as a source image.
                            string inputFilePath = dir + "Gradient.psd";
                            string outputFilePath = outputDir + "16bit " + compression + ", " + byteOrder + ", " + photometric + ", " + planarConfig + ".tif";
                            string etalonFilePath = outputDir + "16bit " + compression + ", " + byteOrder + ", " + photometric + ", " + planarConfig + ".tif";
                            using (Image image = Image.Load(inputFilePath))
                            {
                                image.Save(outputFilePath, options);
                                if (photometric == TiffPhotometrics.Rgb)
                                {
                                    options.BitsPerSample = new ushort[] { 16, 16, 16, 16 };
                                    options.AlphaStorage = TiffAlphaStorage.Associated;
                                    outputFilePath = "16bit " + compression + ", " + byteOrder + ", Rgba, " + planarConfig + ", Associated.tif";
                                    etalonFilePath = "16bit " + compression + ", " + byteOrder + ", Rgba, " + planarConfig + ", Associated.tif";
                                    image.Save(outputFilePath, options);
                                    options.AlphaStorage = TiffAlphaStorage.Unassociated;
                                    outputFilePath = "16bit " + compression + ", " + byteOrder + ", Rgba, " + planarConfig + ", Unassociated.tif";
                                    etalonFilePath = "16bit " + compression + ", " + byteOrder + ", Rgba, " + planarConfig + ", Unassociated.tif";
                                    image.Save(outputFilePath, options);
                                }
                            }
                        }
                    }
                }
            }PSDNET-61 Saving of PSD image produces invalid image colors
 string inputFile = "in.psd";
string outputFile = "out.psd";
using (PsdImage img = (PsdImage)Image.Load(inputFile, new PsdLoadOptions() { ReadOnlyMode = true }))
{
    img.Save(outputFile);
}PSDNET-60 Coordinate of left top corner is incorrect at update
 string sourceFileName = "logodpwit_006.psd";
string outFileNamePngClient = "logodpwit_006_client.png";
string outFileNamePngTopLeftPart = "logodpwit_006_topLeftPart.png";
string outFileNamePngTopLeftFull = "logodpwit_006_topLeftFull.png";
string outFileNamePngBottomRightPart = "logodpwit_006_bottomRightPart.png";
string outFileNamePngBottomRightFull = "logodpwit_006_bottomRightFull.png";
PsdLoadOptions loadOptions = new PsdLoadOptions() { IgnoreTextLayerWidthOnUpdate = true };
PngOptions pngOptions = new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha };
PsdImage image;
TextLayer textLayer;
using (image = Image.Load(sourceFileName, loadOptions) as PsdImage)
{
    foreach (Layer layer in image.Layers)
    {
        textLayer = layer as TextLayer;
        if (textLayer != null && textLayer.Name == "Layer I")
        {
            // client's case
            textLayer.UpdateText("test");
        }
    }
    image.Save(outFileNamePngClient, pngOptions);
}
using (image = Image.Load(sourceFileName, loadOptions) as PsdImage)
{
    foreach (Layer layer in image.Layers)
    {
        textLayer = layer as TextLayer;
        if (textLayer != null && textLayer.Name == "Layer I")
        {
            // partially visible on top left
            textLayer.UpdateText("test", new Point(-100, -100));
        }
    }
    image.Save(outFileNamePngTopLeftPart, pngOptions);
}
using (image = Image.Load(sourceFileName, loadOptions) as PsdImage)
{
    foreach (Layer layer in image.Layers)
    {
        textLayer = layer as TextLayer;
        if (textLayer != null && textLayer.Name == "Layer I")
        {
            // out of bounds on top left
            textLayer.UpdateText("test", new Point(-5, -300));
        }
    }
    image.Save(outFileNamePngTopLeftFull, pngOptions);
}
using (image = Image.Load(sourceFileName, loadOptions) as PsdImage)
{
    foreach (Layer layer in image.Layers)
    {
        textLayer = layer as TextLayer;
        if (textLayer != null && textLayer.Name == "Layer I")
        {
            // partially visible on bottom right
            textLayer.UpdateText("test", new Point(image.Bounds.Right - 200, image.Bounds.Bottom - 200));
        }
    }
    image.Save(outFileNamePngBottomRightPart, pngOptions);
}
using (image = Image.Load(sourceFileName, loadOptions) as PsdImage)
{
    foreach (Layer layer in image.Layers)
    {
        textLayer = layer as TextLayer;
        if (textLayer != null && textLayer.Name == "Layer I")
        {
            // out of bounds on bottom right
            textLayer.UpdateText("test", new Point(image.Bounds.Right + 50, image.Bounds.Bottom + 50));
        }
    }
    image.Save(outFileNamePngBottomRightFull, pngOptions);
}PSDNET-59 Exception on updating text layers
 using (PsdImage image = (PsdImage)PsdImage.Load(sourceFilePath))
{
    foreach (var layer in image.Layers)
    {
        if (layer is TextLayer)
        {
            TextLayer textLayer = (TextLayer)layer;
            if (!String.IsNullOrEmpty(textLayer.Text))
            {
                textLayer.UpdateText("any string");
            }
        }
    }
    image.Save(outputFilePath, new PsdOptions { CompressionMethod = CompressionMethod.RLE });
}PSDNET-58 Expose Codec property of JPEG2000 image to public
 using (Jpeg2000Image image = new Jpeg2000Image(500, 500))
{
    Console.WriteLine(image.Codec.ToString());
}PSDNET-57 Fix 24bpp options setting for export to BMP
 using (Image img = Image.Load(sourceFilePath))
{
    img.Save(outputFilePath, new BmpOptions() { BitsPerPixel = img.BitsPerPixel });
}PSDNET-46 Adjustment layer ignored for CMYK PSD conversion to TIFF or JPG
 // Adjustment layer ignored for CMYK PSD conversion to TIFF or JPG [.Net] (Mask rendering task)
string sourceFileName = "adjustment_layer_small.psd";
string exportPath = "adjustment_layer_small.tif";
using (var im = LoadFile(sourceFileName))
{
     // Export to tif
     psdImage.Save(exportPath, new TiffOptions(TiffExpectedFormat.TiffNoCompressionRgba));
}