繁体   English   中英

尝试使用 Canvas Bitmap 将 C# 中的图片保存到字节数组,但它只输出 2^16 字节

[英]Attempting to save a picture in C# to a Byte Array using Canvas Bitmap but it only ever outputs exactly 2^16 bytes

I am attempting to make a Universal Windows Platform app in C# and I have spent the last week mostly on attempting to get a byte array of a Canvas Bitmap object. At first I thought I could use the Canvas Bitmap function byteArray = pictureBitmap.GetPixelBytes where pictureBitmap is the Canvas Bitmap object that has a loaded image in it.

我做了一些调试,很确定 pictureBitmap 有一个图像保存为 Canvas Bitmap 类型,但是,试图将图像转换为 Byte[] 是一个真正的挑战, GetPixelBytes不会返回 Z099FB3ZF 信息,而只有输出 aF31C54。 bmp 所以我不能真正使用它。

之后,我尝试实现我自己的IRandomAccessStream接口并按照教程进行操作,但是,无论如何,以下代码在第二次调试 output 上仅输出 2^16 个字节,而不是整个图像。

        using (var randomStream = new ImageStream(1000000)) 
        {
            Debug.WriteLine("randomStream Initial Length: " + randomStream.Size);
            await pictureBitmap.SaveAsync(randomStream, CanvasBitmapFileFormat.Jpeg, 0.8f);
            Debug.WriteLine("randomStream After Length: " + randomStream.Size);
        }

对于IRandomAccessStream接口的实现,我尝试了StreamMemoryStream虽然两者都只有 output 一个 65536 字节。 非常感谢任何帮助,谢谢。

编辑

这是我实现接口 IRandomAcessStream 的 ImageStream class 的代码。 如果我不得不猜测问题出在哪里,我相信它可能在FlushAsync()ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)Seek(ulong position)中。 我知道当我将图像保存到文件时,它的大小和格式是正确的,只是在保存到 Stream 时我似乎遇到了麻烦。

class ImageStream : IRandomAccessStream
{
    private MemoryStream internalImageStream;

    public ImageStream()
    {
        internalImageStream = new MemoryStream();
    }
    public ImageStream(int size)
    {
        internalImageStream = new MemoryStream(size);
    }

    public byte[] ConvertToArray()
    {
        return this.internalImageStream.ToArray();
    }

    public int Capacity
    {
        get { return this.internalImageStream.Capacity; }
        set { this.internalImageStream.Capacity = (int)value; }
    }

    public bool CanRead
    {
        get { return true; }
    }

    public bool CanWrite
    {
        get { return true; }
    }

    public ulong Position
    {
        get { return (ulong)this.internalImageStream.Position; }
        set { this.internalImageStream.Position = (long)value; }
    }

    public ulong Size
    {
        get { return (ulong)this.internalImageStream.Length; }
        set { this.internalImageStream.SetLength((long)value); }
    }

    public IRandomAccessStream CloneStream()
    {
        ImageStream newImageStream = new ImageStream();
        newImageStream.internalImageStream = this.internalImageStream;
        return newImageStream;
    }

    public void Dispose()
    {
        this.internalImageStream.Dispose();
    }

    public IAsyncOperation<bool> FlushAsync()
    {
        var outputStream = this.GetOutputStreamAt(0);
        return outputStream.FlushAsync();
    }

    public IInputStream GetInputStreamAt(ulong position)
    {
        this.internalImageStream.Seek((long)position, SeekOrigin.Begin);

        return this.internalImageStream.AsInputStream();
    }

    public IOutputStream GetOutputStreamAt(ulong position)
    {
        this.internalImageStream.Seek((long)position, SeekOrigin.Begin);

        return this.internalImageStream.AsOutputStream();
    }

    public void Seek(ulong position)
    {
        this.internalImageStream.Seek((long)position, 0);
    }

    public IAsyncOperationWithProgress<IBuffer,uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
    {
        var inputStream = this.GetInputStreamAt(0);
        return inputStream.ReadAsync(buffer, count, options);
    }

    public IAsyncOperationWithProgress<uint,uint> WriteAsync(IBuffer buffer)
    {
        var outputStream = this.GetOutputStreamAt(0);
        return outputStream.WriteAsync(buffer);
    }
}

问题出现在ImageStream.WriteAsync方法中。

这个方法在stream写过程中会被多次调用(就像搬东西一样,一次搬不动就搬几次)。 但是在这种方法中,你总是从 0 开始写入,这意味着当你第二次写入时,它会覆盖之前的数据。

尝试这个:

public IAsyncOperationWithProgress<uint, uint> WriteAsync(IBuffer buffer)
{
    var outputStream = this.GetOutputStreamAt(this.Size);
    return outputStream.WriteAsync(buffer);
}

这样可以保证调用会从上次结束的地方继续写,你会得到正确的结果。

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM