我正在制作远程桌面共享应用程序,我在其中捕获桌面图像并压缩它并将其发送到接收器。要压缩图像,我需要将其转换为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但是我无法理解它们。
那么还有其他方法可以实现这个目标吗?
答案 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()
希望有用