C#更改背景颜色标题

时间:2020-05-13 00:44:33

标签: c#

我有一个PNG文件,我想在其中设置/更改标题中的背景颜色。

图片本身不可以编辑。 我在这里谈论标题(https://www.metadata2go.com/file-info/background-color)。我不想更改像素。

尝试过https://docs.microsoft.com/de-de/dotnet/api/system.drawing.image.setpropertyitem?view=dotnet-plat-ext-3.1,但不知道如何添加尚不存在的值以及如何将其与ID匹配。另外,我也不确定这是否正确。

我无能为力,你能帮我吗?

1 个答案:

答案 0 :(得分:0)

感谢艾哈迈德·阿卜杜勒哈米德(Ahmed Abdelhameed),解决方案是https://www.codeproject.com/Articles/16424/Writing-a-Background-Color-bKGD-Chunk-to-a-PNG-Fil

此处代码源: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);
        }
    }
}

用法示例:

 BackgroundHeaderChanger.WriteBackupBackgroundColor(@"C:\TestImg\test.png", Color.Black);