Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions Common_glTF_Exporter/Materials/BitmapsUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,28 @@ public static (string, ImageFormat) GetMimeType(string path)
}
}

/// <summary>
/// Removes non-default gamma or ICC profile metadata from a PNG/JPG file
/// by re-encoding it to a clean sRGB version in memory.
/// </summary>
/// <param name="path">Path to the source image</param>
/// <returns>Byte array of the cleaned image (PNG)</returns>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update documentation to reflect parameterized format.

The documentation states "Byte array of the cleaned image (PNG)" but the method returns the format specified by the imageFormat parameter, which could be JPEG, BMP, or GIF.

Apply this diff:

-    /// <returns>Byte array of the cleaned image (PNG)</returns>
+    /// <returns>Byte array of the cleaned image in the specified format</returns>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/// <returns>Byte array of the cleaned image (PNG)</returns>
/// <returns>Byte array of the cleaned image in the specified format</returns>
🤖 Prompt for AI Agents
In Common_glTF_Exporter/Materials/BitmapsUtils.cs around line 38, the XML
summary/returns documentation incorrectly states the method always returns a PNG
byte array; update the XML comments to reflect that the returned byte array
format is determined by the imageFormat parameter (add/adjust a <param
name="imageFormat"> describing accepted formats and modify the <returns> text to
say it returns a byte array in the specified image format such as PNG, JPEG,
BMP, or GIF). Ensure the doc mentions the imageFormat parameter and that the
return value corresponds to that format.

public static byte[] CleanGamma(string path, ImageFormat imageFormat)
{
using (var original = new Bitmap(path))
using (var ms = new MemoryStream())
{
// Convert to standard sRGB (System.Drawing assumes sRGB by default)
using (var converted = new Bitmap(original.Width, original.Height, PixelFormat.Format24bppRgb))
using (var g = Graphics.FromImage(converted))
{
g.DrawImage(original, 0, 0, original.Width, original.Height);
converted.Save(ms, imageFormat);
}
return ms.ToArray();
}
}
Comment on lines +39 to +53
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Alpha channel is lost when using Format24bppRgb.

The method uses PixelFormat.Format24bppRgb which strips the alpha channel from images with transparency. This will break any textures that require transparency (e.g., cutout materials, decals). glTF fully supports texture transparency, so this data should be preserved.

Apply this diff to preserve alpha:

-                using (var converted = new Bitmap(original.Width, original.Height, PixelFormat.Format24bppRgb))
+                using (var converted = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public static byte[] CleanGamma(string path, ImageFormat imageFormat)
{
using (var original = new Bitmap(path))
using (var ms = new MemoryStream())
{
// Convert to standard sRGB (System.Drawing assumes sRGB by default)
using (var converted = new Bitmap(original.Width, original.Height, PixelFormat.Format24bppRgb))
using (var g = Graphics.FromImage(converted))
{
g.DrawImage(original, 0, 0, original.Width, original.Height);
converted.Save(ms, imageFormat);
}
return ms.ToArray();
}
}
public static byte[] CleanGamma(string path, ImageFormat imageFormat)
{
using (var original = new Bitmap(path))
using (var ms = new MemoryStream())
{
// Convert to standard sRGB (System.Drawing assumes sRGB by default)
using (var converted = new Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb))
using (var g = Graphics.FromImage(converted))
{
g.DrawImage(original, 0, 0, original.Width, original.Height);
converted.Save(ms, imageFormat);
}
return ms.ToArray();
}
}
🤖 Prompt for AI Agents
In Common_glTF_Exporter/Materials/BitmapsUtils.cs around lines 39 to 53, the
current conversion uses PixelFormat.Format24bppRgb which discards the alpha
channel; change the conversion to a 32-bit format that preserves alpha (e.g.,
PixelFormat.Format32bppArgb) and draw the source into that bitmap while ensuring
the Graphics compositing mode preserves alpha (SourceOver/SourceCopy as
appropriate); then save to the MemoryStream with an image format/encoder that
supports alpha (e.g., PNG) or fall back to the provided imageFormat only if it
supports transparency, so transparent pixels are retained for glTF textures.


public static byte[] BlendImageWithColor(
byte[] imageBytes,
double fade,
Expand Down
6 changes: 3 additions & 3 deletions Common_glTF_Exporter/Utils/GLTFBinaryDataUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ public static int ExportImageBuffer(

if (material.pbrMetallicRoughness.baseColorTexture.index == -1)
{
byte[] imageBytes = File.ReadAllBytes(material.EmbeddedTexturePath);
(string , ImageFormat) mimeType = BitmapsUtils.GetMimeType(material.EmbeddedTexturePath);

(string, ImageFormat) mimeType = BitmapsUtils.GetMimeType(material.EmbeddedTexturePath);
byte[] imageBytes = BitmapsUtils.CleanGamma(material.EmbeddedTexturePath, mimeType.Item2);
byte[] blendedBytes = BitmapsUtils.BlendImageWithColor(imageBytes, material.Fadevalue,
material.BaseColor, mimeType.Item2, material.TintColour);

Expand Down
Loading