2016-11-23 142 views
-1

我从char *缓冲区中的服务器接收到一个JPEG图像。我想在保存之前在图片框中显示此图片。我知道的是,图片框可以显示来自File,Hbitmap和Stream的图像。我不想使用这个文件。我不知道如何使用其他的。将char *缓冲区显示为图像

我已经搜索并尝试了一些,这里是我的代码。 我不知道为什么它不显示任何图片。

delegate void setImagedelegate(Stream^image); 
void threadDecodeAndShow() 
    { 
     while (1) 
     { 
      if (f) 
      { 

       //the package that is receiving has some custom headers, 
       // I first find about the size of the JPEG and 
       //put a pointer at the beginning of the JPEG part. 

       BYTE *pImgSur = NULL; 
       DWORD imageInfoLength = *(DWORD*)m_pImgDataBufPtr[nIndexCurBuf]; 
       DWORD customInfoLenForUser = *(DWORD*)(m_pImgDataBufPtr[nIndexCurBuf] + 4 + imageInfoLength); 
       DWORD jpegLength = *(DWORD*)(m_pImgDataBufPtr[nIndexCurBuf] + 4 + imageInfoLength + 4 + customInfoLenForUser); 
       pImgSur = (BYTE *)(m_pImgDataBufPtr[nIndexCurBuf] + 12 + customInfoLenForUser + imageInfoLength); 

       auto store = gcnew array<Byte>(jpegLength); 
       System::Runtime::InteropServices::Marshal::Copy(IntPtr(pImgSur), store, 0, jpegLength); 
       auto stream = gcnew System::IO::MemoryStream(store); 

       this->setImage(stream); 

       f = 0; 
      } 
     } 
    } 
    void setImage(Stream^image) 
    { 
     if (this->pictureBox1->InvokeRequired) 
     { 
      setImagedelegate^ d = 
       gcnew setImagedelegate(this, &MainPage::setImage); 
      this->Invoke(d, gcnew array<Object^> { image }); 
     } 
     else 
     { 

      this->pictureBox1->Image = Image::FromStream(image); 
      this->pictureBox1->Show(); 
     } 
    } 

回答

1

您可以将char *缓冲区转换为具有内存流的流。两种实现方法取决于缓冲区保持有效的时间。 Image类需要该流的后备存储才能在图像的整个生命周期内保持可读性。所以,如果你是100%肯定,你可以依靠的缓冲存活足够长的时间,那么你可以做这样的:

using namespace System; 
using namespace System::Drawing; 

Image^ BytesToImage(char* buffer, size_t len) { 
    auto stream = gcnew System::IO::UnmanagedMemoryStream((unsigned char*)buffer, len); 
    return Image::FromStream(stream); 
} 

如果你没有这样的保证,或者你不能确定,那么你有缓冲区的内容复制:

Image^ BytesToImageBuffered(char* buffer, size_t len) { 
    auto store = gcnew array<Byte>(len); 
    System::Runtime::InteropServices::Marshal::Copy(IntPtr(buffer), store, 0, len); 
    auto stream = gcnew System::IO::MemoryStream(store); 
    return Image::FromStream(stream); 
} 

垃圾收集器负责销毁流和对象数组,你处理的图片对象后会发生,所以没有必要帮助。

+0

谢谢你的回答,尝试了很多东西后,你的解决方案没有错误地工作,但它不显示任何图像。 – Eoaneh

+0

嗯,这段代码不应该“显示任何图像”,它只是转换字节。我不可能猜到,你必须提出另一个问题,并正确记录你对返回的Image对象做了什么。 –

+0

我编辑了我的帖子并添加了代码。你可以请看看吗? – Eoaneh