Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将图像转换为字节数组的最快方法_C#_Memory_Bitmap_Bytearray - Fatal编程技术网

C# 将图像转换为字节数组的最快方法

C# 将图像转换为字节数组的最快方法,c#,memory,bitmap,bytearray,C#,Memory,Bitmap,Bytearray,我正在制作远程桌面共享应用程序,在该应用程序中,我捕获桌面的图像,并将其压缩并发送给接收器。要压缩图像,我需要将其转换为字节[] 目前我使用的是: public byte[] imageToByteArray(System.Drawing.Image imageIn) { MemoryStream ms = new MemoryStream(); imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif); return

我正在制作远程桌面共享应用程序,在该应用程序中,我捕获桌面的图像,并将其压缩并发送给接收器。要压缩图像,我需要将其转换为字节[]

目前我使用的是:

public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
    MemoryStream ms = new MemoryStream();
    imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
    return  ms.ToArray();
}

public Image byteArrayToImage(byte[] byteArrayIn)
{
     MemoryStream ms = new MemoryStream(byteArrayIn);
     Image returnImage = Image.FromStream(ms);
     return returnImage;
}
但我不喜欢它,因为我必须将它保存为ImageFormat,这可能会占用资源(速度减慢)并产生不同的压缩结果。我已经阅读了Marshal.Copy和memcpy,但我无法理解它们

那么,有没有其他方法来实现这一目标

那么,有没有其他方法来实现这一目标

不可以。要将图像转换为字节数组,必须指定图像格式,就像将文本转换为字节数组时必须指定编码一样

如果您担心压缩伪影,请选择无损格式。如果您担心CPU资源,请选择一种不需要压缩的格式—例如,只需原始ARGB像素。当然,这将导致更大的字节数组


请注意,如果您选择了一种包含压缩的格式,那么之后再压缩字节数组是没有意义的——几乎可以肯定没有任何有益的效果。

我不确定您是否会因为Jon Skeet指出的原因而获得巨大的收益。但是,您可以尝试对该方法进行基准测试,并查看它与使用当前方法相比的情况

ImageConverter converter = new ImageConverter();
byte[] imgArray = (byte[])converter.ConvertTo(imageIn, typeof(byte[]));

Image参数有一个RawFormat属性,它返回图像的文件格式。 您可以尝试以下方法:

// extension method
public static byte[] imageToByteArray(this System.Drawing.Image image)
{
    using(var ms = new MemoryStream())
    {
        image.Save(ms, image.RawFormat);
        return ms.ToArray();
    }
}

我能找到的最快方法是:

var myArray = (byte[]) new ImageConverter().ConvertTo(InputImg, typeof(byte[]));

希望有用

MemoryStream和Image都有一个dispose方法,请确保您正在处理它们,因为这可能会导致MemoryStream损坏。@abc123:您不需要处理
MemoryStream
;它是一个完全受管理的资源,除非您在远程处理中使用它。在这两种情况下,处置资源都是不合适的。@JonSkeet有趣的是,你有没有在这方面做过基准测试?查看.net释放对象的速度?我知道DataTable也有类似的参数,但在使用dispose时垃圾收集器收集分配的内存的速度上有明显的差异。@abc123:我真的不希望有这种情况-流的处理不会对数组产生任何影响,MemoryStream也没有终结器(与DataTable不同,DataTable从MarshallByValueComponent继承一个)。有完整源代码的最终解决方案吗?欢迎访问stackoverflow.com,您是否可以添加一些详细信息,解释上面的代码示例为什么会有帮助。这是为其他可能不完全理解它的SO用户提供的…这是针对从文件到字节的解决方案,但OP希望将图形对象转换为字节。图形对象可以存储在数据库中,而不必存储在数据库中将文件系统转换为字节数组,因此必须来回转换…但不能转换为要转换为字节的文件流中的文件-除非可能是在初始上载期间。这对我来说很有帮助,因为我希望对文件执行此操作。很高兴与它相关。无法强制转换“system.Byte[]类型的对象”'to type'System.Drawing.Image'。我建议要么处理MemoryStream,要么将此方法的主体包装在using(){}statement@Neil.Allen我是新来的,你能告诉我为什么吗?@第一步,因为你自己收拾一下:)@我明白了。例程是把我想要执行的任何函数放在using(){}@FirstStep中。更准确地说:如果您使用的对象实现了IDisposable,那么您应该确保在处理完该对象后调用Dispose(),以便它能够清理所有占用的资源。using(){}语句只是在对象超出该语句的范围时为您调用它。因此,您可以使用(myObject){}执行
myObject.Dispose()
——两者都执行相同的操作,但是using语句基本上创建了一个范围,可以为您清理。您可以选择
imageIn.RawFormat
,而不是“选择无损格式”,它尝试保存原始图像字节,而无需进一步重新编码。注意这一点,尤其是在使用WPF时,如果使用的是
System.Windows.Controls.Image
对象。如果要将其中一个转换为字节,并将其作为
InputImg
传递到此行,则此操作无效。它需要一个
System.Drawing.Image
对象。
public static class HelperExtensions
{
    //Convert Image to byte[] array:
    public static byte[] ToByteArray(this Image imageIn)
    {
        var ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        return ms.ToArray();
    }

    //Convert byte[] array to Image:
    public static Image ToImage(this byte[] byteArrayIn)
    {
        var ms = new MemoryStream(byteArrayIn);
        var returnImage = Image.FromStream(ms);
        return returnImage;
    }
}
public static class HelperExtensions
{
    //Convert Image to byte[] array:
    public static byte[] ToByteArray(this Image imageIn)
    {
        var ms = new MemoryStream();
        imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        return ms.ToArray();
    }

    //Convert byte[] array to Image:
    public static Image ToImage(this byte[] byteArrayIn)
    {
        var ms = new MemoryStream(byteArrayIn);
        var returnImage = Image.FromStream(ms);
        return returnImage;
    }
}