如何将图像存储在 JSON 供稿中?

How can I store an image in a JSON feed?

我想在 JSON 格式的数据馈送中包含图像。这样我就可以把图片传给客户端了。

JSON 是基于文本的,因此没有包含其他类型数据的标准方法。但是,您可以将图像(或任何其他二进制内容)'translate' 转换为可包含在 JSON 提要中的 Base64 字符串。

此代码基于 very good blogpost of Jerry Nixon

将这些用法添加到您添加这些方法的 class 中:System.IO、Windows.UI.Xaml.Media、System.Runtime.InteropServices.WindowsRuntime 和 Windows.UI.Xaml.Media.Imaging。 在我的例子中,我用静态方法实现了一个静态 class。

    private static async Task<string> ToBase64(StorageFile bitmap)
    {
        var stream = await bitmap.OpenAsync(Windows.Storage.FileAccessMode.Read);
        var decoder = await BitmapDecoder.CreateAsync(stream);
        var pixels = await decoder.GetPixelDataAsync();
        var bytes = pixels.DetachPixelData();
        return await ToBase64(bytes, (uint)decoder.PixelWidth, (uint)decoder.PixelHeight, decoder.DpiX, decoder.DpiY);
    }

    private static async Task<string> ToBase64(RenderTargetBitmap bitmap)
    {
        var bytes = (await bitmap.GetPixelsAsync()).ToArray();
        return await ToBase64(bytes, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight);
    }

    private static async Task<string> ToBase64(byte[] image, uint height, uint width, double dpiX = 96, double dpiY = 96)
    {
        // encode image
        var encoded = new InMemoryRandomAccessStream();
        var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, encoded);
        encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, height, width, dpiX, dpiY, image);
        await encoder.FlushAsync();
        encoded.Seek(0);

        // read bytes
        var bytes = new byte[encoded.Size];
        await encoded.AsStream().ReadAsync(bytes, 0, bytes.Length);

        // create base64
        return Convert.ToBase64String(bytes);
    }

    public async static Task<string> ConvertFileToBase64(StorageFile file)
    {
        var stream = await file.OpenAsync(FileAccessMode.Read);
        var decoder = await BitmapDecoder.CreateAsync(stream);
        var pixels = await decoder.GetPixelDataAsync();
        var bytes = pixels.DetachPixelData();
        return await ToBase64(bytes, (uint)decoder.PixelWidth, (uint)decoder.PixelHeight, decoder.DpiX, decoder.DpiY);
    }

    public static async Task<ImageSource> FromBase64(string base64)
    {
        // read stream
        var bytes = Convert.FromBase64String(base64);
        var image = bytes.AsBuffer().AsStream().AsRandomAccessStream();

        // decode image
        var decoder = await BitmapDecoder.CreateAsync(image);
        image.Seek(0);

        // create bitmap
        var output = new WriteableBitmap((int)decoder.PixelHeight, (int)decoder.PixelWidth);
        await output.SetSourceAsync(image);
        return output;
    }