将Image转换为Byte数组的最快方法

时间:2013-06-27 19:54:06

标签: c# memory bitmap bytearray

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

目前我正在使用它:

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但是我无法理解它们。

那么还有其他方法可以实现这个目标吗?

6 个答案:

答案 0 :(得分:50)

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

答案 1 :(得分:39)

  

那么还有其他方法可以实现这个目标吗?

没有。为了将图像转换为字节数组,您具有来指定图像格式 - 就像在将文本转换为字节数组时必须指定编码一样。

如果您担心压缩文物,请选择无损格式。如果您担心CPU资源,请选择一种不打扰压缩的格式 - 例如,原始ARGB像素。但当然这会导致更大的字节数组。

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

答案 2 :(得分:13)

我不确定你是否会因为Jon Skeet指出的原因获得任何巨大收益。但是,您可以尝试对TypeConvert.ConvertTo方法进行基准测试,并查看它与使用当前方法的比较。

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

答案 3 :(得分:13)

public static byte[] ReadImageFile(string imageLocation)
    {
        byte[] imageData = null;
        FileInfo fileInfo = new FileInfo(imageLocation);
        long imageFileLength = fileInfo.Length;
        FileStream fs = new FileStream(imageLocation, FileMode.Open, FileAccess.Read);
        BinaryReader br = new BinaryReader(fs);
        imageData = br.ReadBytes((int)imageFileLength);
        return imageData;
    }

答案 4 :(得分:4)

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

答案 5 :(得分:2)

我能找到的最快方法是:

# -*- coding: utf-8 -*-

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
from kivy.lang import Builder
from kivy.clock import mainthread
import sqlite3

import random

class MyBoxLayout(BoxLayout):

    def init(self, **kwargs):
        super().__init__(**kwargs)

        @mainthread  # execute within next frame
        def delayed():
            self.load_random_car()
        delayed()

    def load_random_car(self):
        conn = sqlite3.connect("C:\\test.db")
        cur = conn.cursor()

        cur.execute("SELECT * FROM Cars ORDER BY RANDOM() LIMIT 1;")

        currentAll = cur.fetchone()
        currentAll = list(currentAll)   # Change it from tuple to list
        print currentAll

        current    = currentAll[1]
        self.ids.label.text = current #"fetch random car data from db and put here"


root_widget = Builder.load_string('''
BoxLayout:
    orientation: 'vertical'
    Label:
        id: label
        font_size: 30
    Button:
        size: root.width/2, 15
        text: 'next random'
        font_size: 30
        on_release:  root.load_random_car()

''')


class TestApp(App):
    def build(self):
#        MyBoxLayout(BoxLayout)
        return root_widget

if __name__ == '__main__':
    TestApp().run()

希望有用