简体   繁体   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. 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. 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.

I did some debugging and am pretty sure pictureBitmap has an image saved in it as a Canvas Bitmap type, however, trying to get the image into a Byte[] is a real challenge and GetPixelBytes does not return the header information and only outputs a.bmp so I can't really use that.我做了一些调试,很确定 pictureBitmap 有一个图像保存为 Canvas Bitmap 类型,但是,试图将图像转换为 Byte[] 是一个真正的挑战, GetPixelBytes不会返回 Z099FB3ZF 信息,而只有输出 aF31C54。 bmp 所以我不能真正使用它。

After that I tried implementing my own IRandomAccessStream interface as well as following along with a tutorial, however, no matter what the following code only outputs exactly 2^16 bytes on the second debug output, not the whole image.之后,我尝试实现我自己的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);
        }

For the implementation of the IRandomAccessStream interface I tried both Stream and MemoryStream although both only output a 65536 bytes.对于IRandomAccessStream接口的实现,我尝试了StreamMemoryStream虽然两者都只有 output 一个 65536 字节。 Any help is greatly appreciated, thanks.非常感谢任何帮助,谢谢。

EDIT编辑

This is my code for the ImageStream class which implements the interface IRandomAcessStream.这是我实现接口 IRandomAcessStream 的 ImageStream class 的代码。 If I had to guess where the problem is I believe it could either be in FlushAsync() , ReadAsync(IBuffer buffer, uint count, InputStreamOptions options) , or Seek(ulong position) .如果我不得不猜测问题出在哪里,我相信它可能在FlushAsync()ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)Seek(ulong position)中。 I know that when I save the image to a file it is the correct size and format, it is just when saving to a Stream that I seem to have trouble.我知道当我将图像保存到文件时,它的大小和格式是正确的,只是在保存到 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);
    }
}

The problem appears in the ImageStream.WriteAsync method.问题出现在ImageStream.WriteAsync方法中。

This method will be called multiple times during stream writing (just like moving things, you need to move several times if you can't move at one time).这个方法在stream写过程中会被多次调用(就像搬东西一样,一次搬不动就搬几次)。 But in this method, you always write from 0, which means that when you write the second time, it will overwrite the previous data.但是在这种方法中,你总是从 0 开始写入,这意味着当你第二次写入时,它会覆盖之前的数据。

Try this:尝试这个:

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

This can ensure that the call will continue to write from the place where it last ended, and you will get the correct result.这样可以保证调用会从上次结束的地方继续写,你会得到正确的结果。

Thanks.谢谢。

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

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