【问题标题】:System.ArgumentException at System.Drawing.ImageFromStreamSystem.Drawing.ImageFromStream 处的 System.ArgumentException
【发布时间】:2012-11-10 08:07:34
【问题描述】:

好的,所以我见过很多人遇到这个问题,并且我在某种程度上发现了可能导致问题的原因,但我不知道如何解决它。基本上,我正在尝试通过套接字将屏幕截图从客户端发送到服务器。我在客户端应用程序上截取屏幕截图并使用此方法将其转换为字节数组:

// Convert bitmap to byte method
public static byte[] ImageToByte(Bitmap bitmap)
{
    byte[] imageData;
    using (var stream = new MemoryStream())
    {
        bitmap.Save(stream, ImageFormat.Png);
        imageData = stream.ToArray();
        return imageData;
    }
}

然后我将字节数组的长度和字节数组发送到服务器。服务器收到长度后,使用此方法获取实际数据(这是方法的一部分,因为它大部分不相关):

void dataRecieveCallback(IAsyncResult ar)
{
    try
    {
        int rec = sck.EndReceive(ar);

        if (rec <= 0)
        {
            return;
        }

        recieveBuffer.bufStream.Write(recieveBuffer.buffer, 0, rec);
        recieveBuffer.toRecieve -= rec;

        if (recieveBuffer.toRecieve > 0)
        {
            Array.Clear(recieveBuffer.buffer, 0, recieveBuffer.buffer.Length);
            recieveBuffer.bufStream.Position = 0;
            sck.BeginReceive(recieveBuffer.buffer, 0, recieveBuffer.buffer.Length, SocketFlags.None, dataRecieveCallback, null);
            return;
        }

        // Convert all recieved data in memory stream to a byte array
        byte[] finalBuffer = recieveBuffer.bufStream.ToArray();

然后我使用finalBuffer 尝试获取图像,但每当我这样做时,使用此方法:

        TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
        Bitmap screenShot = (Bitmap)tc.ConvertFrom(finalBuffer);

我总是从System.Drawing.ImageFromStream 得到System.ArgumentException:“参数无效”。这段代码在发送字符串时效果很好,但是每当我尝试发送图像时它都不起作用。我很确定这是套接字代码的问题,因为我尝试通过截屏在本地执行此操作,使用相同的方法将其转换为字节数组,然后使用相同的方法将其转换回来,并且它有效。有人知道我的代码有什么问题吗?

这是缓冲区的部分代码

struct RecBuffer 
{ 
   public const int BUFFER_SIZE = 1024;
   public byte[] buffer;
   public int toRecieve;
   public MemoryStream bufStream;

   public RecBuffer(int toRec) 
   {
      buffer = new byte[BUFFER_SIZE];
      toRecieve = toRec;
      bufStream = new MemoryStream(toRecieve);
   }
}

我使用了大量来自this tutorial 的代码。至少对于接收部分。

【问题讨论】:

  • 您是否调试了 finalBuffer Byte[] 并查看它们是否与源 byte[] 匹配?至少可以比较长度和第一个字节。你的接收方法看起来很奇怪。这个 recieveBuffer 是什么类?
  • 抱歉,我应该发布更多代码。 recieveBuffer 的代码如下所示:struct RecBuffer { public const int BUFFER_SIZE = 1024; public byte[] buffer; public int toRecieve; public MemoryStream bufStream; public RecBuffer(int toRec) { buffer = new byte[BUFFER_SIZE]; toRecieve = toRec; bufStream = new MemoryStream(toRecieve); } 我用了很多这样的人代码:youtube.com/watch?v=PCwS7F2uK3Q
  • 我将此代码放入您的原始帖子中。这样就无法正确读取。那么您是否已经检查了接收字节[]?
  • 是的,对不起。我不习惯这种格式。
  • 好吧,如果你从这个正在工作的人那里得到代码。为什么不通过代码进行调试以找到错误?我不认为我们可以在这里用整个短剪裁来做到这一点。

标签: c# sockets bitmap memorystream


【解决方案1】:

我认为问题出在您的 dataRecieveCallback 函数上。 在那里您将 bufStream 的位置重置为零:

if (recieveBuffer.toRecieve > 0)
{
  Array.Clear(recieveBuffer.buffer, 0, recieveBuffer.buffer.Length);
  recieveBuffer.bufStream.Position = 0; // <--Here
  sck.BeginReceive(recieveBuffer.buffer, 0, recieveBuffer.buffer.Length, SocketFlags.None, dataRecieveCallback, null);
  return;
}

这意味着你下次覆盖已经收到的字节 系统调用你的回调函数。

所以,只需删除该行

recieveBuffer.bufStream.Position = 0;

您的代码应该可以正常工作。

【讨论】:

  • 非常感谢!没有删除它我觉得很愚蠢,这是我在示例代码中的一部分,我只是没有多想。
  • @user1742916:欢迎您!请点击投票箭头下方的空心复选标志接受我的回答。
猜你喜欢
  • 2016-07-08
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 2017-10-29
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
相关资源
最近更新 更多