Thanks to Ahmed Abdelhameed the solution is https://www.codeproject.com/Articles/16424/Writing-a-Background-Color-bKGD-Chunk-to-a-PNG-Fil
Here the Code Source: codeproject !
public class BackgroundHeaderChanger
{
/// <summary>
/// Calculates a byte array containing the calculated CRC.
/// </summary>
/// <param name="buf">The raw data on which to calculate the CRC.</param>
public static byte[] GetCrc(byte[] buffer)
{
uint data = 0xFFFFFFFF;
int n;
if (!IsTableCreated)
CreateCrcTable();
for (n = 0; n < buffer.Length; n++)
data = CrcTable[(data ^ buffer[n]) & 0xff] ^ (data >> 8);
data = data ^ 0xFFFFFFFF;
byte b1 = Convert.ToByte(data >> 24);
byte b2 = Convert.ToByte(b1 << 8 ^ data >> 16);
byte b3 = Convert.ToByte(((data >> 16 << 16) ^ (data >> 8 << 8)) >> 8);
byte b4 = Convert.ToByte((data >> 8 << 8) ^ data);
return new byte[] { b1, b2, b3, b4 };
}
/// <summary>
/// Creates the CRC table for calculating a 32-bit CRC.
/// </summary>
private static void CreateCrcTable()
{
uint c;
int k;
int n;
for (n = 0; n < 256; n++)
{
c = (uint)n;
for (k = 0; k < 8; k++)
{
if ((c & 1) == 1)
{
c = 0xedb88320 ^ (c >> 1);
}
else
{
c = c >> 1;
}
}
CrcTable[n] = c;
}
IsTableCreated = true;
}
static uint[] CrcTable = new uint[256];
static bool IsTableCreated = false;
/// <summary>
/// Writes a backup background color to the specified PNG file.
/// </summary>
/// <param name="fileName">The path and name of the PNG file to write to.</param>
/// <param name="color">The <see cref="Color"/> to set as the backup background color.</param>
public static void WriteBackupBackgroundColor(string fileName, Color color)
{
// Length: 6 bytes, bKGD, then the color
byte[] lengthData = { 0, 0, 0, 6 };
byte[] bkgdChunk = { 98, 75, 71, 68, 0, color.R, 0, color.G, 0, color.B };
byte[] crcData = GetCrc(bkgdChunk);
byte[] data;
using (FileStream fs = new FileStream(fileName, FileMode.Open))
using (BinaryReader binReader = new BinaryReader(fs))
{
data = binReader.ReadBytes((int)binReader.BaseStream.Length);
}
// 18 bytes is the size of a bKGD chunk
byte[] newData = new byte[data.Length + 18];
int dataIndex = 0;
bool wroteChunk = false;
for (int i = 0; i < data.Length; i++)
{
if (!wroteChunk && data[i + 4] == 'I' && data[i + 5] == 'D' && data[i + 6] == 'A' && data[i + 7] == 'T')
{
Array.Copy(lengthData, 0, newData, dataIndex, 4);
dataIndex += 4;
Array.Copy(bkgdChunk, 0, newData, dataIndex, bkgdChunk.Length);
dataIndex += bkgdChunk.Length;
Array.Copy(crcData, 0, newData, dataIndex, 4);
dataIndex += 4;
wroteChunk = true;
}
newData[dataIndex++] = data[i];
}
if (File.Exists(fileName))
File.Delete(fileName);
using (FileStream fs = new FileStream(fileName, FileMode.CreateNew))
using (BinaryWriter binWriter = new BinaryWriter(fs))
{
binWriter.Write(newData);
}
}
}
Usage Example:
BackgroundHeaderChanger.WriteBackupBackgroundColor(@"C:\TestImg\test.png", Color.Black);