我正在尝试创建一个函数,该函数将从URL将PNG加载到内存中,然后使用关键字“ openbadges”和一些json数据添加一个iTXt块。除了执行时,我的所有部分都在工作

metadata.SetQuery("/iTXt/openbadges", "");


我有一个例外:

Value does not fall within the expected range.


这是函数:

private static byte[] CreateOpenBadge(BadgeAssertionEntity assertion)
{
    using (var image = LoadImage(new Uri(assertion.Badge.ImageUrl)))
    using (var imageStream = new MemoryStream())
    {
        image.Save(imageStream, ImageFormat.Png);

        var pngDecoder = new PngBitmapDecoder(imageStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);

        using (var badgeStream = new MemoryStream())
        {
            var pngEncoder = new PngBitmapEncoder();

            pngEncoder.Frames.Add(BitmapFrame.Create(pngDecoder.Frames[0]));

            var metadata = pngEncoder.Frames[0].Metadata as BitmapMetadata;

            if (metadata == null)
                throw new ApplicationException();

            metadata.SetQuery("/iTXt/openbadges", "");

            pngEncoder.Save(badgeStream);

            return badgeStream.ToArray();
        }
    }
}


有什么想法我做错了吗?

最佳答案

诀窍是使用setquery()“ / iTXt / Keyword”和“ / iTXt / TextEntry”,但是必须将char []用作Keyword的值。

这是因为内部“ / iTXt / Keyword”希望将VT_LPSTR作为值类型,并且只有char []可以正确转换为该值。

这是一个使用WIC编写棋盘png(包括一些iTXt元数据)的示例。

using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace PNGEncoder
{
    class Program
    {
        static void Main(string[] args)
        {
            var width = 256;
            var height = 256;

            var pngMetadata = new BitmapMetadata("png");

            pngMetadata.SetQuery("/iTXt/Keyword", "keyword0".ToCharArray());
            pngMetadata.SetQuery("/iTXt/TextEntry", "textentry0");

            pngMetadata.SetQuery("/[1]iTXt/Keyword", "keyword1".ToCharArray());
            pngMetadata.SetQuery("/[1]iTXt/TextEntry", "textentry1");

            var bitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray8, null);

            var pixels = new byte[width * height];
            for (var y = 0; y < height; y++)
            {
                for (var x = 0; x < width; x++)
                {
                    pixels[y * width + x] = (byte)(255 * (((x >> 4) ^ (y >> 4)) & 1));
                }
            }

            bitmap.WritePixels(new Int32Rect(0, 0, width, height), pixels, width, 0);

            var encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bitmap, null, pngMetadata, null));

            using (var stream = File.Create("checkerBoard.png"))
            {
                encoder.Save(stream);
            }
        }
    }
}

07-26 09:36