【问题标题】:How to convert RednerTargetBitmap image into byteArray for uploading on server in UWP如何将 RednerTargetBitmap 图像转换为 byteArray 以在 UWP 中的服务器上上传
【发布时间】:2016-12-16 19:24:14
【问题描述】:

我有一个覆盖整个屏幕的网格,我想将该网格设置为图像,然后将该图像发送到服务器上。我为此目的使用了 RenderTargetBitmap,并成功地使用 FileSave Picker 使 writeablebitmap 保存。图像保存为正常大小,如预期的 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 网格,则上传成功,因为它只有 3 万字节,但上传到服务器上的图像为空或损坏。

我也使用上面转换的 writeablebitmap 来使用这种方法制作它的字节数组...

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

它还返回相同数量的字节数组,并从服务器发生相同的错误。

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

【问题讨论】:

  • 您将原始像素数据与编码图像缓冲区混淆了。使用BitmapEncoder 对位图进行编码,然后传输编码后的缓冲区。
  • clemens 你能提供一些代码帮助吗?在一个函数中,我使用了 BitmapEncoder,但在这一行出现错误。 'var 编码器 = 等待 BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, inMemoryRandomStream);'

标签: c# windows-store-apps uwp windows-10-universal winrt-httpclient


【解决方案1】:

但是当我使用上面的像素字节数组到服务器时。发送请求时 Http 发送任务取消异常,我已对其进行了详细检查。这是由于大量的 Bytes 数组。

我完全同意 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中Image编码详情可以参考Reading and Writing Base64 in the Windows Runtime

【讨论】:

  • 我尝试对图像进行编码,但我在这个 linevar 编码器上遇到错误 = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, encoded);
【解决方案2】:

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

 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();
        }
    }

现在这个方法完美了。

【讨论】:

    猜你喜欢
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    相关资源
    最近更新 更多