我正在尝试创建一个函数,该函数将从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);
}
}
}
}