add support for semi-transparency when overlaying images
This commit is contained in:
parent
99e4a4a1cc
commit
b9844c4acd
|
@ -19,6 +19,7 @@
|
|||
|
||||
* For modders:
|
||||
* Added [data API](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Data).
|
||||
* Added support for overlaying images with semi-transparency using `asset.AsImage().PatchImage`.
|
||||
* Added `IContentPack.WriteJsonFile` method.
|
||||
* Added IntelliSense documentation when not using the 'for developers' version of SMAPI.
|
||||
* Mods are no longer prevented from loading a PNG while the game is drawing.
|
||||
|
|
|
@ -7,6 +7,14 @@ namespace StardewModdingAPI.Framework.Content
|
|||
/// <summary>Encapsulates access and changes to image content being read from a data file.</summary>
|
||||
internal class AssetDataForImage : AssetData<Texture2D>, IAssetDataForImage
|
||||
{
|
||||
/*********
|
||||
** Properties
|
||||
*********/
|
||||
/// <summary>The minimum value to consider non-transparent.</summary>
|
||||
/// <remarks>On Linux/Mac, fully transparent pixels may have an alpha up to 4 for some reason.</remarks>
|
||||
private const byte MinOpacity = 5;
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
|
@ -53,13 +61,38 @@ namespace StardewModdingAPI.Framework.Content
|
|||
// merge data in overlay mode
|
||||
if (patchMode == PatchMode.Overlay)
|
||||
{
|
||||
// get target data
|
||||
Color[] targetData = new Color[pixelCount];
|
||||
target.GetData(0, targetArea, targetData, 0, pixelCount);
|
||||
|
||||
// merge pixels
|
||||
Color[] newData = new Color[targetArea.Value.Width * targetArea.Value.Height];
|
||||
target.GetData(0, targetArea, newData, 0, newData.Length);
|
||||
for (int i = 0; i < sourceData.Length; i++)
|
||||
{
|
||||
Color pixel = sourceData[i];
|
||||
if (pixel.A > 4) // not transparent (note: on Linux/Mac, fully transparent pixels may have an alpha up to 4 for some reason)
|
||||
newData[i] = pixel;
|
||||
Color above = sourceData[i];
|
||||
Color below = targetData[i];
|
||||
|
||||
// shortcut transparency
|
||||
if (above.A < AssetDataForImage.MinOpacity)
|
||||
continue;
|
||||
if (below.A < AssetDataForImage.MinOpacity)
|
||||
{
|
||||
newData[i] = above;
|
||||
continue;
|
||||
}
|
||||
|
||||
// merge pixels
|
||||
// This performs a conventional alpha blend for the pixels, which are already
|
||||
// premultiplied by the content pipeline.
|
||||
float alphaAbove = above.A / 255f;
|
||||
float alphaBelow = (255 - above.A) / 255f;
|
||||
newData[i] = new Color(
|
||||
r: (int)((above.R * alphaAbove) + (below.R * alphaBelow)),
|
||||
g: (int)((above.G * alphaAbove) + (below.G * alphaBelow)),
|
||||
b: (int)((above.B * alphaAbove) + (below.B * alphaBelow)),
|
||||
a: Math.Max(above.A, below.A)
|
||||
);
|
||||
}
|
||||
sourceData = newData;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue