@DJCWanderer could you please provide input file and minimum required code to reproduce the issue. Your case can be different from the case of topic starter. Release 25.1 is already published. Release 25.2 is planned on the 20th of February estimately.
We’ve observed that the issue occurs when writing XMP to the file and then saving it. However, if XMP is not written back to the file, the save operation is successful. I’ve created a simplified code snippet that writes an XMP and then saves the file.
public void WriteXMP(string filePath)
{
try
{
string stringXmp = "<xmpMapping><add namespace=\"http://purl.org/dc/elements/1.1/\" prefix=\"dc\" name=\"summary\">\"Test\"</add></xmpMapping>";
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
XDocument xmpMapping = XDocument.Parse(stringXmp);
using (img)
{
Console.WriteLine("Checking for existing XMP Data");
XmpPacketWrapper xmpData = img.XmpData;
if (xmpData == null)
{
Console.WriteLine("Writing new XMP Data");
// Create xmp metadata if the image doesn't contains any xmp data.
XmpHeaderPi xmpHeader = new XmpHeaderPi(Guid.NewGuid().ToString());
XmpTrailerPi xmpTrailer = new XmpTrailerPi(true);
XmpMeta xmpMeta = new XmpMeta();
xmpData = new XmpPacketWrapper(xmpHeader, xmpTrailer, xmpMeta);
img.XmpData = xmpData;
}
Console.WriteLine("Writing XMP Data");
foreach (var mapping in xmpMapping.Descendants("xmpMapping").Elements("add"))
{
var xmpNamespace = mapping.Attribute("namespace").Value;
var xmpName = mapping.Attribute("name").Value;
var xmpPrefix = mapping.Attribute("prefix").Value;
var xmpValue = mapping.Value;
if (xmpData.ContainsPackage(xmpNamespace))
{
// Update or add XMP property value in existing namespace
foreach (var xmpPackage in xmpData.Packages)
{
if (xmpPackage.NamespaceUri.Trim().ToLower() == xmpNamespace.Trim())
{
if (xmpPackage.ContainsKey(xmpPackage.Prefix + ":" + xmpName))
{
xmpPackage[(xmpPackage.Prefix + ":" + xmpName)] = xmpValue;
}
else
{
xmpPackage.AddValue(xmpPackage.Prefix + ":" + xmpName, xmpValue);
}
}
}
}
else
{
// Create XMP namespace, since it does not yet exist
XmpBasicPackage xmp = new XmpBasicPackage(xmpPrefix, xmpNamespace);
xmp.AddValue(xmpPrefix + ":" + xmpName, xmpValue);
xmpData.AddPackage(xmp);
}
}
Console.WriteLine("Saving File..");
img.Save(filePath);
stopwatch.Stop();
Console.WriteLine($"Elapsed Time: {stopwatch.Elapsed} (hh:mm:ss:ms)");
Console.WriteLine("Saving Done");
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
You can used the file from my previous post as it is still available and this code used the latest 25.1
I know this is a free support but can you please give us any updates on your findings after this since we also need to give an update to our customer.
Thanks,
Mark
@3stan team works on this issue. At this moment “Index Out of Range” exception is fixed, also speed of processing improved, but the final file can not be opened with PS. The work continues.
@3stan it’s still planned on 25.2, but in the worst case release of this feature will be moved to 25.3
We really need this in 25.2 because of its impact on our customers. If it doesn’t make it in time, would your team be able to patch it on top of 25.2?
@3stan team is actively work on this task. But I can not guarantee that it will be fixed in the top of February.
Any updates on the fix? Are the fix can still make it on 25.2 release? We need to get the updates on the progress as we also need to update our customer.
Thanks
@3stan the issue was more complex. At this moment the issue with saving of files larger than 2gb is fixed. Also, rendering of masks were optimized. The fix should be presented in 25.2
Just want to clarify some things
What to you mean on “the issue was more complex”
- Does this mean that there are still issues?
And
The fix should be present in 25.2
- Does this mean that the saving of files larger than 2gb is fix and be available in 25.2?
- Does the issue on opening of the new generated psb file is also fix and be available on 25.2?
- Is the index out of bound issue will be resolved on 25.2?
Thanks
- Issue with saving file larger than 2Gb is fixed
- Opening and saving of PSB files work fine
- Index out of bounds is fixed
This provided file after the saving still have the visual artifacts. They can be fixed, but the rendering speed will slow down on 25%.
Release 25.2 is planned on the 20th of February estimately.
@Dmitriy.Sorokin, is there update on the 25.2 release?
The issues you have found earlier (filed as PSDNET-2288) have been fixed in this update. This message was posted using Bugs notification tool by yaroslav.lisovskyi
This issue was verified as fixed; however, a problem persists when saving a 2GB PSB file to Azure Blob Storage. The “Index Out of Bound” error still occurs in our lab environment, where all files are stored in Azure Blob Storage. However, in the local environment, where files are saved to local storage, the fix works correctly. Any suggestions on resolving this?
@3stan could you please additionally check if the old version of Aspose.PSD was not cached and correctly updated. Please check if the version of .NET the same in Azure Blob Storage and locally.
Also, please check if the code locally and in the lab environment differs, also please check if the file the same.
> the old version of Aspose.PSD was not cached and correctly updated - No other version exist and already cleared the cache. Also the logs show it is using 25.2 version
> Please check if the version of .NET the same in Azure Blob Storage and locally - This is the same. Although in local we are using Emulator for Blob storage. So the file is stored locally
> Also, please check if the code locally and in the lab environment differs - Same code on both local and lab environment.
> also please check if the file the same. - Yes both are the same.
I tried Adding PSDLoadOption and I’ve noticed that when I set the ReadOnlyMode = true, the file is being saved but it does not write any XMP back.
Here is the full code:
private bool UpdateXmpMetadata(UpdateXmpMetadataMediaAction action)
{
if (!string.IsNullOrEmpty(action.XmpMetadataMapping))
{
PsdImage img = null;
// First attempt to load the PSD/PSB file
try
{
var loadOptions = new PsdLoadOptions()
{
BufferSizeHint = 50 * 1048576,
ReadOnlyMode = false,
LoadEffectsResource = false, // Faster loading by skipping layer effects
UseDiskForLoadEffectsResource = true // Prevents high RAM usage for large files
};
using (var inputStream = File.OpenRead(action.Path))
{
img = (PsdImage)Image.Load(inputStream, loadOptions);
}
}
catch (ImageLoadException e)
{
// Cannot suppport PSD/PSB files with Multichannel or Duotone color mode at this time due to known Aspose bug
if (e.Message.ToLower().Contains("image") && e.InnerException.Message.ToLower().Contains("color mode") && e.InnerException.Message.ToLower().Contains("compression"))
{
throw new MediaEngineException("PSD/PSB files with Multichannel or Duotone color mode are not supported.", false);
}
}
catch (Exception)
{
// Something unexpected went wrong while loading
throw;
}
// Since we loaded successfully, process it
using (img)
{
// Cannot suppport PSD/PSB files with Lab color mode which have 16 bits per channel at this time due to known Aspose bug
if (img.ColorMode == ColorModes.Lab && img.BitsPerChannel == 16)
{
throw new MediaEngineException("PSD/PSB files with Lab color mode which have 16 bits per channel are not supported.", false);
}
// Cannot suppport PSD/PSB files with CMYK color mode which have less than 4 or more than 5 channels at this time due to known Aspose bug
if (img.ColorMode == ColorModes.Cmyk && (img.ChannelsCount < 4 || img.ChannelsCount > 5))
{
throw new MediaEngineException("PSD/PSB files with CMYK color mode must have 4 or 5 channels.", false);
}
// Cannot suppport PSD/PSB files with RGB/Lab color mode which have less than 3 or more than 4 channels at this time due to known Aspose bug
if ((img.ColorMode == ColorModes.Rgb || img.ColorMode == ColorModes.Lab) && (img.ChannelsCount < 3 || img.ChannelsCount > 4))
{
throw new MediaEngineException("PSD/PSB files with RGB/Lab color must have 3 or 4 channels.", false);
}
XDocument xmpMapping = XDocument.Parse(action.XmpMetadataMapping);
// Getting the xmp metadata
XmpPacketWrapper xmpData = img.XmpData;
if (xmpData == null)
{
// Create xmp metadata if the image doesn't contains any xmp data.
XmpHeaderPi xmpHeader = new XmpHeaderPi(Guid.NewGuid().ToString());
XmpTrailerPi xmpTrailer = new XmpTrailerPi(true);
XmpMeta xmpMeta = new XmpMeta();
xmpData = new XmpPacketWrapper(xmpHeader, xmpTrailer, xmpMeta);
img.XmpData = xmpData;
}
foreach (var mapping in xmpMapping.Descendants("xmpMapping").Elements("add"))
{
var xmpNamespace = mapping.Attribute("namespace").Value;
var xmpName = mapping.Attribute("name").Value;
var xmpPrefix = mapping.Attribute("prefix").Value;
var xmpValue = mapping.Value;
if (xmpData.ContainsPackage(xmpNamespace))
{
// Update or add XMP property value in existing namespace
foreach (var xmpPackage in xmpData.Packages)
{
if (xmpPackage.NamespaceUri.Trim().ToLower() == xmpNamespace.Trim())
{
if (xmpPackage.ContainsKey(xmpPackage.Prefix + ":" + xmpName))
{
xmpPackage[(xmpPackage.Prefix + ":" + xmpName)] = xmpValue;
}
else
{
xmpPackage.AddValue(xmpPackage.Prefix + ":" + xmpName, xmpValue);
}
}
}
}
else
{
// Create XMP namespace, since it does not yet exist
XmpBasicPackage xmp = new XmpBasicPackage(xmpPrefix, xmpNamespace);
xmp.AddValue(xmpPrefix + ":" + xmpName, xmpValue);
xmpData.AddPackage(xmp);
}
}
img.Save(action.OutputPath);
}
return true;
}
return false;
}
The Code Above works when it is deployed on local environment, however, different behavior when it is on Lab environment where all files are coming from Azure Blob Storage. But when a file is less than 2GB even with a 1.7GB. All are working even on Lab.
This is the error message we’ve got. Note that this is only happening when the file is not on the local storage and file size is 2gb or larger
Adam.Core.MediaEngines.MediaEngineException: Action UpdateXmpMetadata failed to execute using all engines. The last engine (AsposePsd) failed with error “Index was outside the bounds of the array.”. —> System.IndexOutOfRangeException: Index was outside the bounds of the array. at Aspose.PSD.FileFormats.Psd.Layers.ChannelInformation.(Byte[] , Size , Rectangle ) at …(Dictionary2 , Size , Rectangle ) at ..Process(Rectangle , Int32[] , Point , Point ) at .. (Rectangle ) at .( , IList
1 , ) at .(Rectangle , , , Int32 , Int32 , ) at .(Rectangle , , ) at .(Object ) at .(MethodBase , Boolean ) at .() at .(Boolean ) at .(Object ) at .() at .(Object , UInt32 ) at .(Boolean ) at .(Object[] , Type[] , Type[] , Object[] ) at .LoadPartialArgb32Pixels(Rectangle , IPartialArgb32PixelLoader ) at . (Rectangle ) at .( , IList1 , ) at .(Rectangle , , , Int32 , Int32 , ) at . (Rectangle , IPartialArgb32PixelLoader ) at .(Int32 , IColorPalette , , Int32 ) at .(StreamContainer , Int32 , IColorPalette , , Int32 ) at Aspose.PSD.FileFormats.Psd.PsdImage.SaveData(Stream stream) at Aspose.PSD.DataStreamSupporter.Save(Stream stream) at Aspose.PSD.DataStreamSupporter.Save(String filePath) at Adam.Core.MediaEngines.AsposePsdMediaEngine.UpdateXmpMetadata(UpdateXmpMetadataMediaAction action) at Adam.Core.MediaEngines.MediaManager.RunAction(MediaAction action, IMediaEngine engine, Exception& exception) --- End of inner exception stack trace --- at Adam.Core.MediaEngines.MediaManager.LogActionFailure(MediaAction action, IMediaEngine lastFailedEngine, Exception lastException) at Adam.Core.MediaEngines.MediaManager.RunInternal(IEnumerable
1 engines, IEnumerable`1 actions) at Adam.Core.Orders.UpdateXmpMetadataOrderTargetAction.OnExecute() at Adam.Core.Orders.OrderRunner.ExecuteRegisteredActions()
@3stan we need additional time to investigate it. What’s version of .NET is used? Possible, Stream/StreamContainer classes behavior is different.