通过 API 在 PSD 文件中编辑光栅图层蒙版

概述

为了自动化 PSD 格式的编辑并在没有 Adobe® Photoshop® 的情况下更改 PSD 文件,您可以使用下面提供的 Aspose.PSD API。以下是可以帮助您修改 PSD 文件的 C# 和 .NET 代码片段。

使用 PSD 图层和矢量蒙版,我们能够在不永久删除它们的情况下隐藏和显示图层像素。光栅蒙版也称为图层蒙版或用户蒙版。在 Aspose.PSD 中,可以通过LayerMaskData图层属性访问光栅和矢量蒙版,它可以是 ‘LayerMaskDataShort’ 和 ‘LayerMaskDataFull’ 类的实例,这些类是抽象 ‘LayerMaskData’ 类的子类。如果一个图层同时具有光栅和矢量蒙版,则会提供LayerMaskDataFull实例。如果一个图层只有光栅蒙版或矢量蒙版,则会提供LayerMaskDataShort实例。如果 LayerMaskData 属性为 null,则表示该图层没有蒙版或仅有一个禁用的矢量蒙版。

todo:image_alt_text

一个光栅蒙版和一个禁用的矢量蒙版 LayerMaskDataShort

一个禁用的光栅蒙版 LayerMaskDataShort

一个光栅蒙版和一个矢量蒙版 LayerMaskDataFull

一个光栅蒙版 LayerMaskDataShort

一个矢量蒙版 LayerMaskDataShort

一个禁用的矢量蒙版 null(但矢量资源存在)

如何在 PSD 文件中获取图层光栅蒙版?

首先,我们应该查找图层是否同时具有矢量和图层蒙版:

以下提供的示例代码演示了如何获取图层光栅蒙版

LayerMaskDataFull fullMask = layer.LayerMaskData as LayerMaskDataFull;
if (fullMask != null)
{
var left = fullMask.EnclosingLeft;
var right = fullMask.EnclosingRight;
var top = fullMask.EnclosingTop;
var bottom = fullMask.EnclosingBottom;
var maskRectangle = fullMask.UserMaskRectangle;
var imageData = fullMask.UserMaskData;
var defaultColor = fullMask.BackgroundColor;
var flags = fullMask.RealFlags;
bool isDisabled = (flags & LayerMaskFlags.Disabled) != 0;
}

否则,LayerMaskData 图层属性的类型为 LayerMaskDataShort。在这种情况下,让我们检查图层是否只有一个光栅蒙版,方法是检查 Flags 属性。它不应该包含 LayerMaskFlags.UserMaskFromRenderingOtherData 标志,否则该蒙版是矢量蒙版缓存。

获取蒙版代码段:

LayerMaskDataShort mask = (LayerMaskDataShort)layer.LayerMaskData;
if ((mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) == 0)
{
var left = fullMask.Left;
var right = fullMask.Right;
var top = fullMask.Top;
var bottom = fullMask.Bottom;
var maskRectangle = mask.MaskRectangle;
var imageData = mask.ImageData;
var defaultColor = newMask.DefaultColor;
var flags = newMask.Flags;
bool isDisabled = (flags & LayerMaskFlags.Disabled) != 0;
}

如果需要提取光栅蒙版作为 LayerMaskDataShort(用于进一步操作),即使两种蒙版都存在,也应提取并转换为 LayerMaskDataShort。下面的代码可以同时用于这两种情况:

从 PSD 中提取光栅蒙版

LayerMaskDataShort GetRasterMask(LayerMaskData mask)
{
LayerMaskDataFull fullMask = mask as LayerMaskDataFull;
if (mask == null ||
((mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) != 0 && fullMask == null))
{
return null;
}
if (fullMask != null)
{
return new LayerMaskDataShort()
{
Left = fullMask.EnclosingLeft,
Right = fullMask.EnclosingRight,
Top = fullMask.EnclosingTop,
Bottom = fullMask.EnclosingBottom,
ImageData = fullMask.UserMaskData,
DefaultColor = fullMask.DefaultColor,
Flags = fullMask.RealFlags
};
}

如何检查 PSD 文件中的图层是否具有光栅蒙版?

以下的 C# 代码可能会帮助您检查图层是否具有光栅蒙版:

如何知道是否将光栅蒙版应用于PSD 图层

bool HasLayerRasterMask(Layer layer)
{
var mask = layer.LayerMaskData;
var fullMask = mask as LayerMaskDataFull;
if (mask == null ||
((mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) != 0 && fullMask == null))
{
return false;
}
return true;
}

如何在 PSD 文件中删除 / 添加 / 更新图层光栅蒙版?

仅删除 / 添加 / 更新 LayerMaskData 是不够的以便正确保存,因为通道不会被更新;尽管它可能提供正确的渲染。这并不会更改蒙版通道:

layer.LayerMaskData = newMaskData;

我们应该使用 layer AddLayerMask 方法来删除 / 添加 / 更新。

这会同时添加 / 更新蒙版和通道:

layer.AddLayerMask(newMaskData);

这会同时删除蒙版和通道:

在 PSD 图像中删除图层光栅蒙版

首先,我们检查蒙版是否处于短格式,并且如果不是矢量蒙版,我们可以只调用 AddLayerMask 方法并输入 null 来删除光栅蒙版。但如果蒙版处于完整格式,我们必须将其转换为短格式,仅保留矢量蒙版。要删除图层蒙版,可以使用以下 C# .NET 代码段:

代码段如何从 PSD 文件中删除图层蒙版。

void RemoveRasterMask(Layer layer)
{
LayerMaskData mask = layer.LayerMaskData;
LayerMaskDataFull fullMask = mask as LayerMaskDataFull;
if (mask == null ||
((mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) != 0 && fullMask == null))
{
throw new Exception("This layer has no raster mask.");
}
if (fullMask == null)
{
layer.AddLayerMask(null);
return;
}
var vectorMask = new LayerMaskDataShort();
vectorMask.Flags = fullMask.Flags;
vectorMask.MaskRectangle = fullMask.MaskRectangle;
vectorMask.DefaultColor = fullMask.DefaultColor;
vectorMask.ImageData = fullMask.ImageData;
layer.AddLayerMask(vectorMask);
}

更新 PSD 图像中的图层光栅蒙版

这很简单:如果蒙版处于短格式,则必须根据需要更改 ImageData 和 MaskRectangle。否则,UserMaskDataUserMaskRectangle应更改。以下的 C# .NET 代码段可用于更新图层蒙版:

使用 C# 更新 PSD 图层蒙版

void RemoveRasterMask(Layer layer)
{
LayerMaskData mask = layer.LayerMaskData;
LayerMaskDataFull fullMask = mask as LayerMaskDataFull;
if (mask == null ||
((mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) != 0 && fullMask == null))
{
throw new Exception("This layer has no raster mask.");
}
if (fullMask == null)
{
layer.AddLayerMask(null);
return;
}
var vectorMask = new LayerMaskDataShort();
vectorMask.Flags = fullMask.Flags;
vectorMask.MaskRectangle = fullMask.MaskRectangle;
vectorMask.DefaultColor = fullMask.DefaultColor;
vectorMask.ImageData = fullMask.ImageData;
layer.AddLayerMask(vectorMask);
}

这是一个可能改变光栅蒙版的示例操作。这个操作反转了图层用户蒙版:

使用 C# 更新 PSD 图层蒙版

void InvertMask(LayerMaskData mask)
{
byte[] maskBytes;
LayerMaskDataFull fullMask = mask as LayerMaskDataFull;
if (fullMask == null)
{
maskBytes = mask.ImageData;
}
else
{
maskBytes = fullMask.UserMaskData;
}
for (int i = 0; i < maskBytes.Length; i++)
{
maskBytes[i] = (byte)~maskBytes[i];
}
}

更新 PSD 文件中的图层光栅蒙版时如何处理矢量蒙版存在的情况

假设用户已经更改了矢量路径资源。然后,它可以通过调用AddLayerMask图层方法简单地更新矢量蒙版:

使用 C# 更新PSD 图层矢量蒙版

void UpdateVectorMask(Layer layer)
{
var vectorMask = layer.LayerMaskData;
if (vectorMask == null || (vectorMask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) == 0)
{
throw new Exception("This layer has no vector mask.");
}
layer.AddLayerMask(vectorMask);
}

在 PSD 文件中添加图层光栅蒙版

如果一个图层没有蒙版,我们可以通过调用 AddLayerMask 图层方法简单地添加给定的光栅蒙版。

如果这个蒙版没有UserMaskFromRenderingOtherData**标志,那么它已经有一个光栅蒙版,并且我们必须像上面描述的方式更新它。否则,如果这个蒙版是短格式,我们将其转换为完整格式。否则,我们将其原样使用。然后根据给定的蒙版属性更新 UserMaskData、UserMaskRectangle 和其他属性。以下的 C# .NET 代码段可用于添加(更新)图层蒙版:

将新的图层蒙版添加到 PSD 文件

void AddRasterMask(LayerMaskData mask, LayerMaskDataShort newShortMask)
{
LayerMaskData mask = layer.LayerMaskData;
LayerMaskDataFull fullMask = mask as LayerMaskDataFull;
var hasRasterMask = fullMask != null ||
(mask != null && (mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) == 0);
if (hasRasterMask)
{
Console.WriteLine("This layer has a raster mask already, updating.");
}
if (mask != null)
{
if (fullMask != null)
{
// let's update user raster mask in a full one.
fullMask.RealFlags = newMask.Flags;
fullMask.DefaultColor = newMask.DefaultColor;
fullMask.UserMaskRectangle = newMask.MaskRectangle;
fullMask.UserMaskData = newMask.ImageData;
newMask = fullMask;
}
else if ((mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) != 0)
{
// let's convert the short raster mask to a full one.
fullMask = new LayerMaskDataFull();
fullMask.Flags = mask.Flags;
fullMask.MaskRectangle = mask.MaskRectangle;
fullMask.ImageData = mask.ImageData;
fullMask.RealFlags = newMask.Flags;
fullMask.DefaultColor = newMask.DefaultColor;
fullMask.UserMaskRectangle = newMask.MaskRectangle;
fullMask.UserMaskData = newMask.ImageData;
newMask = fullMask;
}
}
// Adds or updates a mask
layer.AddLayerMask(newMask);
}

如何检查图层蒙版是否启用?

要了解图层光栅蒙版的启用状态,我们可以检查 LayerMaskDataShort 的 Flags 属性或 LayerMaskDataFull 的 RealFlags 中的 LayerMaskFlags.Disabled 标志状态。以下的 C# .NET 代码段可用于获取图层蒙版的启用状态:

检查蒙版是否启用:

bool GetRasterMaskState(Layer layer)
{
var mask = layer.LayerMaskData;
var fullMask = mask as LayerMaskDataFull;
if (mask == null || ((mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) != 0 &&
fullMask == null))
{
throw new Exception("This layer has no raster mask.");
}
if (fullMask != null)
{
return (fullMask.RealFlags & LayerMaskFlags.Disabled) == 0;
}
else
{
return (mask.Flags & LayerMaskFlags.Disabled) == 0;
}
}

如何启用或禁用光栅图层蒙版?

要启用或禁用图层光栅蒙版,我们可以更改 LayerMaskDataShort 的 Flags 属性或 LayerMaskDataFull 的 RealFlags 中的 LayerMaskFlags.Disabled 标志状态。以下的 C# .NET 代码段可用于更改图层蒙版的启用状态:

启用或禁用光栅图层蒙版:

void SetRasterMaskState(Layer layer, bool isEnabled)
{
var mask = layer.LayerMaskData;
var fullMask = mask as LayerMaskDataFull;
if (mask == null || ((mask.Flags & LayerMaskFlags.UserMaskFromRenderingOtherData) != 0 &&
fullMask == null))
{
throw new Exception("This layer has no raster mask."));
}
if (fullMask != null)
{
if (isEnabled)
{
fullMask.RealFlags = fullMask.RealFlags & ~LayerMaskFlags.Disabled;
}
else
{
fullMask.RealFlags = fullMask.RealFlags | LayerMaskFlags.Disabled;
}
}
else
{
{
if (isEnabled)
{
mask.Flags = mask.Flags & ~LayerMaskFlags.Disabled;
}
else
{
mask.Flags = mask.Flags | LayerMaskFlags.Disabled;
}
}
}
}