これは何度も尋ねられてきたことを知っています...私はすべての検索と試行を行っていますが、なぜ "パラメータが有効ではありません"という例外...System.Drawing.Imageパラメータが無効
Windows Server 2012を実行しているAmazon EC2インスタンスがあります。そのマシンでは、Unity3D(Unity 5)を実行しています。そのUnityアプリケーションは、TCPを介してEC2インスタンスから私のローカルラップトップにフレーム(画像)を送信しています。私のクライアントはWindows 10を実行していますが、違いはありません。
私の画像データを取得するために、私は次のようにします。
byte[] GetScreenData() {
// Create a texture the size of the screen, RGB24 format
int width = Screen.width;
int height = Screen.height;
RenderTexture rt = new RenderTexture(width, height, 24);
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
Camera camera = GameObject.Find("Main Camera").GetComponent <Camera>();
camera.targetTexture = rt;
camera.Render();
RenderTexture.active = rt;
// Read screen contents into the texture
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
camera.targetTexture = null;
RenderTexture.active = null;
Destroy(rt);
// Encode texture into JPG
byte[] bytes = tex.EncodeToJPG();
Destroy(tex);
return bytes;
}
私はその後FlatBuffersを使って自分のデータをシリアル化:
public static byte[] FlatSerialize(this ServerToClientMessage message) {
var builder = new FlatBufferBuilder(1);
//Create an ID
var MessageId = builder.CreateString(message.MessageId.ToString());
//Start the vector...
//Loop over each byte and add it - my god, is there not a better way?
FlatServerToClientMessage.StartImagebytesVector(builder, message.ImageBytes.Length);
foreach(var imageByte in message.ImageBytes) {
builder.AddByte(imageByte);
}
var imagebytes = builder.EndVector();
//Start the FlatServerToClientMessage and add the MessageId and imagebytes
FlatServerToClientMessage.StartFlatServerToClientMessage(builder);
FlatServerToClientMessage.AddMessageid(builder, MessageId);
FlatServerToClientMessage.AddImagebytes(builder, imagebytes);
//End the FlatServerToClientMessage and finish it...
var flatMessage = FlatServerToClientMessage.EndFlatServerToClientMessage(builder);
FlatServerToClientMessage.FinishFlatServerToClientMessageBuffer(builder, flatMessage);
return builder.SizedByteArray();
}
次に、私は私のデータを送信します。
public void SendRaw(byte[] dataToSend) {
///We must send the length of the message before sending the actual message
var sizeInfo = new byte[4]; // = BitConverter.GetBytes(dataToSend.Length);
//Shift the bytes
sizeInfo[0] = (byte) dataToSend.Length;
sizeInfo[1] = (byte)(dataToSend.Length >> 8);
sizeInfo[2] = (byte)(dataToSend.Length >> 16);
sizeInfo[3] = (byte)(dataToSend.Length >> 24);
try {
var stream = Client.GetStream();
//Send the length of the data
stream.Write(sizeInfo, 0, 4);
//Send the data
stream.Write(dataToSend, 0, dataToSend.Length);
} catch (Exception ex) {
Debug.LogException(ex);
} finally {
//raise event to tell system that the client has disconnected and that listening must restart...
}
}
私のクライアントデバイスに戻ると、デシリアライズしてイベントを発生させる受信データを聞いています。 Oデシリアライズするには
private void Run() {
try {
// ShutdownEvent is a ManualResetEvent signaled by
// Client when its time to close the socket.
while (!ShutDownEvent.WaitOne(0)) {
try {
if (!_stream.DataAvailable) continue;
//Read the first 4 bytes which represent the size of the message, and convert from byte array to int32
var sizeinfo = new byte[4];
_stream.Read(sizeinfo, 0, 4);
var messageSize = BitConverter.ToInt32(sizeinfo, 0);
//create a new buffer for the data to be read
var buffer = new byte[messageSize];
var read = 0;
//Continue reading from the stream until we have read all bytes @messageSize
while (read != messageSize) {
read += _stream.Read(buffer, read, buffer.Length - read);
}
var message = new ServerToClientMessage().FlatDeserialize(buffer);
//raise data received event
OnDataReceived(message);
} catch (IOException ex) {
// Handle the exception...
}
}
} catch (Exception ex) {
// Handle the exception...
} finally {
_stream.Close();
}
}
...新しいイメージの到着にシステムを警告、私は次のようにします。明確にするため
public static ServerToClientMessage FlatDeserialize(this ServerToClientMessage message, byte[] bytes) {
var bb = new ByteBuffer(bytes);
var flatmessage = FlatServerToClientMessage.GetRootAsFlatServerToClientMessage(bb);
message.MessageId = new Guid(flatmessage.Messageid);
message.ImageBytes = new byte[flatmessage.ImagebytesLength];
for (var i = 0; i < flatmessage.ImagebytesLength; i++) {
message.ImageBytes[i] = flatmessage.GetImagebytes(i);
}
return message;
}
、ここServerToClientMessage
クラスがある:
public class ServerToClientMessage : EventArgs
{
public Guid MessageId { get; set; }
public byte[] ImageBytes { get; set; }
}
とにかく、OnDataReceived
イベントが発生し、ImageBytes
配列からSystem.Drawing.Imageに変換する関数が呼び出されます。その機能はここにあります:
public Image byteArrayToImage(byte[] byteArrayIn) {
// SAME PROBLEM!
//var converter = new System.Drawing.ImageConverter();
// return (Image)converter.ConvertFrom(byteArrayIn); ;
using(var memoryStream = new MemoryStream(byteArrayIn)) {
return Image.FromStream(memoryStream, false, false);
}
}
私の画像データはサーバから送られてきましたが、私はそれを検証しました。 JSONを使用すると、これはすべて正常に動作します。私は、バイト配列からImageに変換する多くの方法を試しましたが、私はいつもParameter is not valid
例外を表示するようです。私はまた、JPGやPNGのようなさまざまなフォーマットで画像を送ろうとしました。
誰でも知っていますか?