如何将 RednerTargetBitmap 图像转换为 byteArray 以便在 UWP 中上传到服务器

How to convert RednerTargetBitmap image into byteArray for uploading on server in UWP

我有一个覆盖整个屏幕的网格,我想将该网格制作为图像,然后我想将此图像发送到服务器上。为此,我使用了 RenderTargetBitmap,并使用 FileSave Picker 成功制作了可写位图以进行保存。图像保存为正常大小,如预期的 700kb,但这些字节对于在服务器上上传来说太大了。 700kb 图像的预期字节数可能为 20 万,但在我的情况下,字节数超过 300 万。字节肯定有问题。 这是我使用文件保存选择器将网格保存为图像的代码。

        await bitmap.RenderAsync(testgrid);
        var pixelBuffer = await bitmap.GetPixelsAsync();
        byte[] pixels = pixelBuffer.ToArray();
        var wb = new WriteableBitmap((int)bitmap.PixelWidth, (int)bitmap.PixelHeight);
        using (stream2 = wb.PixelBuffer.AsStream())
        {
            await stream2.WriteAsync(pixels, 0, pixels.Length);            
        }
        FileSavePicker picker = new FileSavePicker();

        picker.FileTypeChoices.Add("JPG File", new List<string>() { ".jpg" });

        StorageFile file = await picker.PickSaveFileAsync();
        if (file != null)
        {
            await (wb as WriteableBitmap).SaveAsync(file);
        }   

以上代码成功将图像以正常大小保存到给定位置。 但是当我使用上面的像素字节数组到服务器时。 Http 发送任务在发送请求时取消了异常,我已经对其进行了详细检查。这是由于大量的字节数组。 此外,如果我发送一个非常小的 50x50 网格,则上传成功,因为它只有 30,000 字节,但上传到服务器上的图像是空的或已损坏。

我还使用上面转换的 writeablebitmap 使用此方法制作其字节数组...

using (Stream stream = mywriteablebitmap.PixelBuffer.AsStream())
        using (MemoryStream memoryStream = new MemoryStream())
        {
            stream.CopyTo(memoryStream);
            return memoryStream.ToArray();
        }

它也 returns 相同数量的字节数组和服务器发生相同的错误。

请告诉我从 RenderTargetBitmap 制作字节数组的正确方法,并且可以轻松上传到服务器。

but when i use above pixel byte array to server. Http send task cancelled exception while send request and i have detail checked on it. It is due to huge amount of Bytes array.

我完全同意 Clemens,您需要在上传图片之前对其进行编码。您可以使用以下代码对图像进行编码:

private async Task<String> ToBase64(byte[] image, uint height, uint width, double dpiX = 96, double dpiY = 96)
{
    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);

    var bytes = new byte[encoded.Size];
    await encoded.AsStream().ReadAsync(bytes, 0, bytes.Length);
    var base64String=Convert.ToBase64String(bytes);
    return base64String;
}

并在您的代码中调用它:

var pixelBuffer = await bitmap.GetPixelsAsync();
byte[] pixels = pixelBuffer.ToArray();
await ToBase64(pixels, (uint)bitmap.PixelHeight, (uint)bitmap.PixelWidth);

关于在WinRT中对图像进行编码的详细信息,您可以参考Reading and Writing Base64 in the Windows Runtime

经过大量搜索后,我将 renderTargetBitmap 保存到 isolatedstorage 中,然后从存储中访问图像文件并使用此方法制作其流字节数组。

 var stream = await imageStorageFile.OpenStreamForReadAsync();
        imageBytes=ReadFully(stream);

  public byte[] ReadFully(Stream input)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }

现在这个方法完美了。