Aspose.PSD for .NET 19.9 - Release Notes
**
Key | Summary | Category |
---|---|---|
PSDNET-160 | Wrong layer name extracted | Feature |
PSDNET-175 | Getting text properties from a different portion of text inside PSD TextLayer | Feature |
PSDNET-190 | Support for Add layer group | Feature |
PSDNET-192 | Support of Scale Property for Gradient Fill Layer | Feature |
PSDNET-162 | Adjusting Brightness | Enhancement |
PSDNET-174 | IndexOutOfRangeException on saving PSD image as JPEG | Bug |
PSDNET-180 | Updating text layer text throws an exception | Bug |
PSDNET-182 | Saving PSD image after RotateFlip operation produces a corrupted file which could not be open | Bug |
Public API Changes
Added APIs:
- M:Aspose.PSD.FileFormats.Psd.Layers.LayerGroup.AddLayerGroup(System.String,System.Int32)
- T:Aspose.PSD.FileFormats.Psd.Layers.Text.IText
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.IText.Items
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.IText.Text
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.IText.ProducePortion
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.IText.AddPortion(Aspose.PSD.FileFormats.Psd.Layers.Text.ITextPortion)
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.IText.InsertPortion(Aspose.PSD.FileFormats.Psd.Layers.Text.ITextPortion,System.Int32)
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.IText.RemovePortion(System.Int32)
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.IText.UpdateLayerData
- T:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.Justification
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.FirstLineIndent
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.StartIndent
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.EndIndent
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.SpaceBefore
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.SpaceAfter
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.AutoHyphenate
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.HyphenatedWordSize
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.PreHyphen
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.PostHyphen
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.ConsecutiveHyphens
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.Zone
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.WordSpacing
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.LetterSpacing
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.GlyphSpacing
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.AutoLeading
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.LeadingType
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.Hanging
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.Burasagari
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.KinsokuOrder
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.EveryLineComposer
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.Apply(Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph)
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph.IsEqual(Aspose.PSD.FileFormats.Psd.Layers.Text.ITextParagraph)
- T:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextPortion
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextPortion.Text
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextPortion.Style
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextPortion.Paragraph
- T:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.FontSize
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.AutoLeading
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.Leading
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.Tracking
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.Kerning
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.FillColor
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.StrokeColor
- P:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.HindiNumbers
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.Apply(Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle)
- M:Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle.IsEqual(Aspose.PSD.FileFormats.Psd.Layers.Text.ITextStyle)
- P:Aspose.PSD.FileFormats.Psd.Layers.TextLayer.TextData
- P:Aspose.PSD.FileFormats.Psd.Layers.FillSettings.IGradientFillSettings.Scale
- P:Aspose.PSD.FileFormats.Psd.Layers.LayerResources.GdFlResource.Scale
- P:Aspose.PSD.FileFormats.Psd.Layers.FillSettings.GradientFillSettings.Scale
Removed APIs:
- None
Usage examples:
PSDNET-160. Wrong layer name extracted
To display the layer name properly use the DisplayName property. A setter is now added for this property and the property can be modified. When Photoshop is saving layer name using the Name property the Korean characters are stored as byte 63'?' in ASCII. Use the DisplayName property because the Name property does not support Korean characters.
// make changes in layer names and save it
using (var image = (PsdImage)Image.Load("layers with names.psd"))
{
for (int i = 0; i < image.Layers.Length; i++)
{
var layer = image.Layers[i];
// set new value into DisplayName property
layer.DisplayName += "_changed";
}
image.Save("output.psd");
}
PSDNET-175. Getting text properties from a different portion of text inside PSD TextLayer
const double Tolerance = 0.0001;
var filePath = "ThreeColorsParagraphs.psd";
var outputPath = "ThreeColorsParagraph_out.psd";
using (var im = (PsdImage)Image.Load(filePath))
{
for (int i = 0; i < im.Layers.Length; i++)
{
var layer = im.Layers[i] as TextLayer;
if (layer != null)
{
var portions = layer.TextData.Items;
if (portions.Length != 4)
{
throw new Exception();
}
// Checking text of every portion
if (portions[0].Text != "Old " ||
portions[1].Text != "color" ||
portions[2].Text != " text\r" ||
portions[3].Text != "Second paragraph\r")
{
throw new Exception();
}
// Checking paragraphs data
// Paragraphs have different justification
if (
portions[0].Paragraph.Justification != 0 ||
portions[1].Paragraph.Justification != 0 ||
portions[2].Paragraph.Justification != 0 ||
portions[3].Paragraph.Justification != 2)
{
throw new Exception();
}
// All other properties of first and second paragraph are equal
for (int j = 0; j < portions.Length; j++)
{
var paragraph = portions[j].Paragraph;
if (Math.Abs(paragraph.AutoLeading - 1.2) > Tolerance ||
paragraph.AutoHyphenate != false ||
paragraph.Burasagari != false ||
paragraph.ConsecutiveHyphens != 8 ||
Math.Abs(paragraph.StartIndent) > Tolerance ||
Math.Abs(paragraph.EndIndent) > Tolerance ||
paragraph.EveryLineComposer != false ||
Math.Abs(paragraph.FirstLineIndent) > Tolerance ||
paragraph.GlyphSpacing.Length != 3 ||
Math.Abs(paragraph.GlyphSpacing[0] - 1) > Tolerance ||
Math.Abs(paragraph.GlyphSpacing[1] - 1) > Tolerance ||
Math.Abs(paragraph.GlyphSpacing[2] - 1) > Tolerance ||
paragraph.Hanging != false ||
paragraph.HyphenatedWordSize != 6 ||
paragraph.KinsokuOrder != 0 ||
paragraph.LetterSpacing.Length != 3 ||
Math.Abs(paragraph.LetterSpacing[0]) > Tolerance ||
Math.Abs(paragraph.LetterSpacing[1]) > Tolerance ||
Math.Abs(paragraph.LetterSpacing[2]) > Tolerance ||
paragraph.LeadingType != LeadingMode.Auto ||
paragraph.PreHyphen != 2 ||
paragraph.PostHyphen != 2 ||
Math.Abs(paragraph.SpaceBefore) > Tolerance ||
Math.Abs(paragraph.SpaceAfter) > Tolerance ||
paragraph.WordSpacing.Length != 3 ||
Math.Abs(paragraph.WordSpacing[0] - 0.8) > Tolerance ||
Math.Abs(paragraph.WordSpacing[1] - 1.0) > Tolerance ||
Math.Abs(paragraph.WordSpacing[2] - 1.33) > Tolerance ||
Math.Abs(paragraph.Zone - 36.0) > Tolerance)
{
throw new Exception();
}
}
// Checking style data
// Styles have different colors and font size
if (Math.Abs(portions[0].Style.FontSize - 12) > Tolerance ||
Math.Abs(portions[1].Style.FontSize - 12) > Tolerance ||
Math.Abs(portions[2].Style.FontSize - 12) > Tolerance ||
Math.Abs(portions[3].Style.FontSize - 10) > Tolerance)
{
throw new Exception();
}
if (portions[0].Style.FillColor != Color.FromArgb(255, 145, 0, 0) ||
portions[1].Style.FillColor != Color.FromArgb(255, 201, 128, 2) ||
portions[2].Style.FillColor != Color.FromArgb(255, 18, 143, 4) ||
portions[3].Style.FillColor != Color.FromArgb(255, 145, 42, 100))
{
throw new Exception();
}
for (int j = 0; j < portions.Length; j++)
{
var style = portions[j].Style;
if (style.AutoLeading != false ||
style.HindiNumbers != false ||
style.Kerning != 0 ||
style.Leading != 0 ||
style.StrokeColor != Color.FromArgb(255, 175, 90, 163) ||
style.Tracking != 50)
{
throw new Exception();
}
}
// Example of text editing
portions[0].Text = "Hello ";
portions[1].Text = "World";
// Example of text portions removing
layer.TextData.RemovePortion(3);
layer.TextData.RemovePortion(2);
// Example of adding new text portion
var createdPortion = layer.TextData.ProducePortion();
createdPortion.Text = "!!!\r";
layer.TextData.AddPortion(createdPortion);
portions = layer.TextData.Items;
// Example of paragraph and style editing for portions
// Set right justification
portions[0].Paragraph.Justification = 1;
portions[1].Paragraph.Justification = 1;
portions[2].Paragraph.Justification = 1;
// Different colors for each style. The will be changed, but rendering is not fully supported
portions[0].Style.FillColor = Color.Aquamarine;
portions[1].Style.FillColor = Color.Violet;
portions[2].Style.FillColor = Color.LightBlue;
// Different font. The will be changed, but rendering is not fully supported
portions[0].Style.FontSize = 6;
portions[1].Style.FontSize = 8;
portions[2].Style.FontSize = 10;
layer.TextData.UpdateLayerData();
im.Save(outputPath, new PsdOptions(im));
break;
}
}
}
PSDNET-190. Support for Add layer group
// -Group 1
// --Layer 1
// --Group 2
// ---Layer 2
// ---Layer 3
// --Layer 4
string dataDir = "psdnet190_test.psd";
var createOptions = new PsdOptions();
createOptions.Source = new FileCreateSource(dataDir, false);
createOptions.Palette = new PsdColorPalette(new Color[] { Color.Green });
using (var psdImage = (PsdImage)Image.Create(createOptions, 500, 500))
{
LayerGroup group1 = psdImage.AddLayerGroup("Group 1", 0, true);
Layer layer1 = new Layer(psdImage);
layer1.Name = "Layer 1";
group1.AddLayer(layer1);
LayerGroup group2 = group1.AddLayerGroup("Group 2", 1);
Layer layer2 = new Layer(psdImage);
layer2.Name = "Layer 2";
group2.AddLayer(layer2);
Layer layer3 = new Layer(psdImage);
layer3.Name = "Layer 3";
group2.AddLayer(layer3);
Layer layer4 = new Layer(psdImage);
layer4.Name = "Layer 4";
group1.AddLayer(layer4);
psdImage.Save();
}
PSDNET-192. Support of Scale Property for Gradient Fill Layer
using (var image = (PsdImage)Image.Load("FillLayerGradient.psd"))
{
// getting a fill layer
FillLayer fillLayer = null;
foreach (var layer in image.Layers)
{
fillLayer = layer as FillLayer;
if (fillLayer != null)
{
break;
}
}
var settings = fillLayer.FillSettings as IGradientFillSettings;
// update scale value
settings.Scale = 200;
fillLayer.Update(); // Updates pixels data
image.Save("scaledImage.png", new PngOptions() { ColorType = PngColorType.TruecolorWithAlpha });
}
PSDNET-174. IndexOutOfRangeException on saving PSD image as JPEG
using (var image = Aspose.PSD.Image.Load("SamplePSD.psd"))
{
image.Save("sampleJPG.jpg", new JpegOptions());
}
PSDNET-180. Updating text layer text throws an exception
// Updating text layer text throws exception
string filePath = "FlipVertical.psd";
string outputPath = "FlipVertical_changed.psd";
var newText = "Test";
using (var image = Image.Load(filePath))
{
var psdImage = image as PsdImage;
if (image == null)
{
return;
}
var layers = psdImage.Layers;
for (var index = layers.Length - 1; index >= 0; index--)
{
var layer = layers[index] as TextLayer;
if (layer == null)
{
continue;
}
layer.UpdateText(newText);
}
var imageOptions = new PsdOptions(psdImage);
psdImage.Save(outputPath, imageOptions);
}
PSDNET-182. Saving PSD image after RotateFlip operation produces a corrupted file which could not be open
string sourceFileName = "1.psd";
RotateFlipType flipType = RotateFlipType.Rotate270FlipXY;
string outFileNamePsd = "RotateFlipTest2617.psd";
using (PsdImage image = (PsdImage)Image.Load(sourceFileName))
{
image.RotateFlip(flipType);
image.Save(outFileNamePsd);
}
// Should be executed without exceptions
using (PsdImage image = (PsdImage)Image.Load(outFileNamePsd))
{
// Do nothing
}