0

我有一个覆盖整个屏幕的网格,我想将该网格制作为图像,然后将该图像发送到服务器上。我为此目的使用了 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 制作字节数组的正确方法,并且可以很容易地上传到服务器上。

4

2 回答 2

0

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

我完全同意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 的详细信息,您可以参考在 Windows 运行时读取和写入 Base64

于 2016-08-11T09:42:27.387 回答
0

经过大量搜索后,我将 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();
        }
    }

现在这种方法很完美。

于 2016-08-20T11:33:02.307 回答