这是段客户端接收winsock传过来的图片直接在picture中显示的代码:    Dim bytData() As Byte '接收图片
    Dim PBag As New PropertyBag '图片信息    ReDim bytData(1 To Winsock1.BytesReceived) '接收图片大小
    
    Winsock1.GetData bytData '读取缓冲区数据
    
    PBag.Contents = bytData
    Set Picture1.Picture = PBag.ReadProperty("Picture") '设置图片
    
    cmdReceive.Enabled = False在本地运行服务端和客户端没问题通过,但两台电脑分别运行服务端和客户端就有问题了,客户端
PBag.Contents = bytData   报错:  无效的过程调用或参数请问这个怎么解决呢?

解决方案 »

  1.   

    楼主是想将图片数据通过winsock传输,对方接收成功后再还原成图片,对吧。
    完全可以通过流的方式进行,并且在处理过程中对图像进行jpeg压缩,可大大提高数据的传输量,参考如下:首先要下载一个IStream库,用该库可以减少代码量,如果直接全部用API也未尝不可。
    IStream下载地址:IStream.zip
    下面是代码,可以贴在一个模块中:Option Explicit'常量声明
    Private Const ClsidJPEG As String = "{557CF401-1A04-11D3-9A73-0000F81EF32E}"
    Private Const EncoderParameterValueTypeLong As Long = 4&
    Private Const EncoderQuality As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"
    Private Const GdiPlusVersion As Long = 1&'结构声明
    Private Type GUID
        Data1 As Long
        Data2 As Integer
        Data3 As Integer
        Data4(0 To 7) As Byte
    End TypePrivate Type IID
        Data1 As Long
        Data2 As Integer
        Data3 As Integer
        Data4(0 To 7)  As Byte
    End TypePrivate Type PICTDESC
        cbSizeOfStruct As Long
        picType As Long
        hgdiObj As Long
        hPalOrXYExt As Long
    End TypePrivate Type EncoderParameter
        GUID As GUID
        NumberOfValues As Long
        Type As Long
        Value As Long
    End TypePrivate Type EncoderParameters
        Count As Long
        Parameter(15) As EncoderParameter
    End TypePrivate Type GDIPlusStartupInput
        GdiPlusVersion As Long
        DebugEventCallback As Long
        SuppressBackgroundThread As Long
        SuppressExternalCodecs As Long
    End TypePrivate Type GdiplusStartupOutput
        NotificationHook As Long
        NotificationUnhook As Long
    End Type'枚举声明
    Private Enum Status
        OK = 0
        GenericError = 1
        InvalidParameter = 2
        OutOfMemory = 3
        ObjectBusy = 4
        InsufficientBuffer = 5
        NotImplemented = 6
        Win32Error = 7
        WrongState = 8
        Aborted = 9
        FileNotFound = 10
        ValueOverflow = 11
        AccessDenied = 12
        UnknownImageFormat = 13
        FontFamilyNotFound = 14
        FontStyleNotFound = 15
        NotTrueTypeFont = 16
        UnsupportedGdiplusVersion = 17
        GdiplusNotInitialized = 18
        PropertyNotFound = 19
        PropertyNotSupported = 20
        ProfileNotFound = 21
    End Enum'API声明
    Private Declare Function GdipCreateBitmapFromHBITMAP Lib "gdiplus" (ByVal hbm As Long, ByVal hpal As Long, ByRef bitmap As Long) As Status
    Private Declare Function GdipCreateHBITMAPFromBitmap Lib "gdiplus" (ByVal bitmap As Long, ByRef hbmReturn As Long, ByVal Background As Long) As Status
    Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal image As Long) As Status
    Private Declare Function GdipLoadImageFromStream Lib "gdiplus" (ByVal Stream As IUnknown, ByRef image As Long) As Status
    Private Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long) As Status
    Private Declare Function GdiplusStartup Lib "gdiplus" (ByRef token As Long, ByRef lpInput As GDIPlusStartupInput, ByRef lpOutput As GdiplusStartupOutput) As Status
    Private Declare Function GdipSaveImageToStream Lib "gdiplus" (ByVal image As Long, ByVal Stream As IStream, ByRef clsidEncoder As GUID, ByRef encoderParams As Any) As Status
    Private Declare Function CLSIDFromString Lib "ole32" (ByVal Str As Long, ByRef id As GUID) As Long
    Private Declare Function CreateStreamOnHGlobal Lib "ole32.dll" (ByRef hGlobal As Any, ByVal fDeleteOnRelease As Long, ByRef ppstm As Any) As Long
    Private Declare Sub OleCreatePictureIndirect Lib "oleaut32.dll" (ByRef lpPictDesc As PICTDESC, ByRef riid As IID, ByVal fOwn As Boolean, ByRef lplpvObj As Object)
    '根据版本初始化GDI+
    Private Function StartUpGDIPlus(ByVal GdipVersion As Long) As Long
        Dim GdipToken As Long
        Dim GdipStartupInput As GDIPlusStartupInput
        Dim GdipStartupOutput As GdiplusStartupOutput
        GdipStartupInput.GdiPlusVersion = GdipVersion
        If GdiplusStartup(GdipToken, GdipStartupInput, GdipStartupOutput) = OK Then
            StartUpGDIPlus = GdipToken
        End If
    End Function'从图像转换为流
    Public Function PictureToStream(ByVal Picture As StdPicture, Optional ByVal JpegQuality As Long = 85) As IStream
        Dim picStream As IStream
        Dim lBitmap As Long
        Dim tGUID As GUID
        Dim bytBuff() As Byte
        Dim tParams As EncoderParameters
        Dim lngGdipToken As Long
        
        lngGdipToken = StartUpGDIPlus(GdiPlusVersion)    '检查JPG压缩比率
        If JpegQuality > 100 Then JpegQuality = 100
        If JpegQuality < 0 Then JpegQuality = 0    '创建Bitmap
        If GdipCreateBitmapFromHBITMAP(Picture.Handle, 0, lBitmap) = OK Then
            '创建Stream
            If CreateStreamOnHGlobal(ByVal 0, False, picStream) = 0 Then
                '转换GUID
                If CLSIDFromString(StrPtr(ClsidJPEG), tGUID) = 0 Then
                    '设置JPG相关参数值
                    tParams.Count = 1
                    With tParams.Parameter(0)
                        CLSIDFromString StrPtr(EncoderQuality), .GUID
                        .NumberOfValues = 1
                        .Type = EncoderParameterValueTypeLong
                        .Value = VarPtr(JpegQuality)
                    End With
                    '将Bitmap数据保存到流(JPG格式)
                    If GdipSaveImageToStream(lBitmap, picStream, tGUID, tParams) = OK Then
                        Set PictureToStream = picStream
                    End If
                End If
                Set picStream = Nothing
            End If
        End If
        GdipDisposeImage lBitmap
        GdiplusShutdown lngGdipToken
    End Function'从流转换为图像
    Public Function StreamToPicture(ByVal Stream As IStream) As StdPicture
        Dim picStream As IStream
        Dim lBitmap As Long
        Dim hBitmap As Long
        Dim lngGdipToken As Long
        Dim tPictDesc As PICTDESC
        Dim IID_IPicture As IID
        Dim oPicture As IPicture    lngGdipToken = StartUpGDIPlus(GdiPlusVersion)    Set picStream = Stream
        '从Stream加载Bitmap
        If GdipLoadImageFromStream(picStream, lBitmap) = OK Then
            '根据Bitmap创建hBitbmp
            If GdipCreateHBITMAPFromBitmap(lBitmap, hBitmap, 0) = OK Then
                With tPictDesc
                    .cbSizeOfStruct = Len(tPictDesc)
                    .picType = vbPicTypeBitmap
                    .hgdiObj = hBitmap
                    .hPalOrXYExt = 0
                End With            ' 初始化IPicture
                With IID_IPicture
                    .Data1 = &H7BF80981
                    .Data2 = &HBF32
                    .Data3 = &H101A
                    .Data4(0) = &H8B
                    .Data4(1) = &HBB
                    .Data4(3) = &HAA
                    .Data4(5) = &H30
                    .Data4(6) = &HC
                    .Data4(7) = &HAB
                End With            Call OleCreatePictureIndirect(tPictDesc, IID_IPicture, True, oPicture)
                Set StreamToPicture = oPicture
            End If
        End If    Set picStream = Nothing
        GdipDisposeImage lBitmap
        GdiplusShutdown lngGdipToken
    End Function
    测试代码:'示例
    Private Sub Command1_Click()
        Dim s As IStream
        Set s = PictureToStream(Me.Picture1.Picture)
        Set Me.Picture2.Picture = StreamToPicture(s)
    End Sub
    不知楼主是否看的明白,可再回复。
      

  2.   

    楼主是想将图片数据通过winsock传输,对方接收成功后再还原成图片,对吧。
    完全可以通过流的方式进行,并且在处理过程中对图像进行jpeg压缩,可大大提高数据的传输量,参考如下:首先要下载一个IStream库,用该库可以减少代码量,如果直接全部用API也未尝不可。
    IStream下载地址:IStream.zip
    下面是代码,可以贴在一个模块中:Option Explicit'常量声明
    Private Const ClsidJPEG As String = "{557CF401-1A04-11D3-9A73-0000F81EF32E}"
    Private Const EncoderParameterValueTypeLong As Long = 4&
    Private Const EncoderQuality As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"
    Private Const GdiPlusVersion As Long = 1&'结构声明
    Private Type GUID
        Data1 As Long
        Data2 As Integer
        Data3 As Integer
        Data4(0 To 7) As Byte
    End TypePrivate Type IID
        Data1 As Long
        Data2 As Integer
        Data3 As Integer
        Data4(0 To 7)  As Byte
    End TypePrivate Type PICTDESC
        cbSizeOfStruct As Long
        picType As Long
        hgdiObj As Long
        hPalOrXYExt As Long
    End TypePrivate Type EncoderParameter
        GUID As GUID
        NumberOfValues As Long
        Type As Long
        Value As Long
    End TypePrivate Type EncoderParameters
        Count As Long
        Parameter(15) As EncoderParameter
    End TypePrivate Type GDIPlusStartupInput
        GdiPlusVersion As Long
        DebugEventCallback As Long
        SuppressBackgroundThread As Long
        SuppressExternalCodecs As Long
    End TypePrivate Type GdiplusStartupOutput
        NotificationHook As Long
        NotificationUnhook As Long
    End Type'枚举声明
    Private Enum Status
        OK = 0
        GenericError = 1
        InvalidParameter = 2
        OutOfMemory = 3
        ObjectBusy = 4
        InsufficientBuffer = 5
        NotImplemented = 6
        Win32Error = 7
        WrongState = 8
        Aborted = 9
        FileNotFound = 10
        ValueOverflow = 11
        AccessDenied = 12
        UnknownImageFormat = 13
        FontFamilyNotFound = 14
        FontStyleNotFound = 15
        NotTrueTypeFont = 16
        UnsupportedGdiplusVersion = 17
        GdiplusNotInitialized = 18
        PropertyNotFound = 19
        PropertyNotSupported = 20
        ProfileNotFound = 21
    End Enum'API声明
    Private Declare Function GdipCreateBitmapFromHBITMAP Lib "gdiplus" (ByVal hbm As Long, ByVal hpal As Long, ByRef bitmap As Long) As Status
    Private Declare Function GdipCreateHBITMAPFromBitmap Lib "gdiplus" (ByVal bitmap As Long, ByRef hbmReturn As Long, ByVal Background As Long) As Status
    Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal image As Long) As Status
    Private Declare Function GdipLoadImageFromStream Lib "gdiplus" (ByVal Stream As IUnknown, ByRef image As Long) As Status
    Private Declare Function GdiplusShutdown Lib "gdiplus" (ByVal token As Long) As Status
    Private Declare Function GdiplusStartup Lib "gdiplus" (ByRef token As Long, ByRef lpInput As GDIPlusStartupInput, ByRef lpOutput As GdiplusStartupOutput) As Status
    Private Declare Function GdipSaveImageToStream Lib "gdiplus" (ByVal image As Long, ByVal Stream As IStream, ByRef clsidEncoder As GUID, ByRef encoderParams As Any) As Status
    Private Declare Function CLSIDFromString Lib "ole32" (ByVal Str As Long, ByRef id As GUID) As Long
    Private Declare Function CreateStreamOnHGlobal Lib "ole32.dll" (ByRef hGlobal As Any, ByVal fDeleteOnRelease As Long, ByRef ppstm As Any) As Long
    Private Declare Sub OleCreatePictureIndirect Lib "oleaut32.dll" (ByRef lpPictDesc As PICTDESC, ByRef riid As IID, ByVal fOwn As Boolean, ByRef lplpvObj As Object)
    '根据版本初始化GDI+
    Private Function StartUpGDIPlus(ByVal GdipVersion As Long) As Long
        Dim GdipToken As Long
        Dim GdipStartupInput As GDIPlusStartupInput
        Dim GdipStartupOutput As GdiplusStartupOutput
        GdipStartupInput.GdiPlusVersion = GdipVersion
        If GdiplusStartup(GdipToken, GdipStartupInput, GdipStartupOutput) = OK Then
            StartUpGDIPlus = GdipToken
        End If
    End Function'从图像转换为流
    Public Function PictureToStream(ByVal Picture As StdPicture, Optional ByVal JpegQuality As Long = 85) As IStream
        Dim picStream As IStream
        Dim lBitmap As Long
        Dim tGUID As GUID
        Dim bytBuff() As Byte
        Dim tParams As EncoderParameters
        Dim lngGdipToken As Long
        
        lngGdipToken = StartUpGDIPlus(GdiPlusVersion)    '检查JPG压缩比率
        If JpegQuality > 100 Then JpegQuality = 100
        If JpegQuality < 0 Then JpegQuality = 0    '创建Bitmap
        If GdipCreateBitmapFromHBITMAP(Picture.Handle, 0, lBitmap) = OK Then
            '创建Stream
            If CreateStreamOnHGlobal(ByVal 0, False, picStream) = 0 Then
                '转换GUID
                If CLSIDFromString(StrPtr(ClsidJPEG), tGUID) = 0 Then
                    '设置JPG相关参数值
                    tParams.Count = 1
                    With tParams.Parameter(0)
                        CLSIDFromString StrPtr(EncoderQuality), .GUID
                        .NumberOfValues = 1
                        .Type = EncoderParameterValueTypeLong
                        .Value = VarPtr(JpegQuality)
                    End With
                    '将Bitmap数据保存到流(JPG格式)
                    If GdipSaveImageToStream(lBitmap, picStream, tGUID, tParams) = OK Then
                        Set PictureToStream = picStream
                    End If
                End If
                Set picStream = Nothing
            End If
        End If
        GdipDisposeImage lBitmap
        GdiplusShutdown lngGdipToken
    End Function'从流转换为图像
    Public Function StreamToPicture(ByVal Stream As IStream) As StdPicture
        Dim picStream As IStream
        Dim lBitmap As Long
        Dim hBitmap As Long
        Dim lngGdipToken As Long
        Dim tPictDesc As PICTDESC
        Dim IID_IPicture As IID
        Dim oPicture As IPicture    lngGdipToken = StartUpGDIPlus(GdiPlusVersion)    Set picStream = Stream
        '从Stream加载Bitmap
        If GdipLoadImageFromStream(picStream, lBitmap) = OK Then
            '根据Bitmap创建hBitbmp
            If GdipCreateHBITMAPFromBitmap(lBitmap, hBitmap, 0) = OK Then
                With tPictDesc
                    .cbSizeOfStruct = Len(tPictDesc)
                    .picType = vbPicTypeBitmap
                    .hgdiObj = hBitmap
                    .hPalOrXYExt = 0
                End With            ' 初始化IPicture
                With IID_IPicture
                    .Data1 = &H7BF80981
                    .Data2 = &HBF32
                    .Data3 = &H101A
                    .Data4(0) = &H8B
                    .Data4(1) = &HBB
                    .Data4(3) = &HAA
                    .Data4(5) = &H30
                    .Data4(6) = &HC
                    .Data4(7) = &HAB
                End With            Call OleCreatePictureIndirect(tPictDesc, IID_IPicture, True, oPicture)
                Set StreamToPicture = oPicture
            End If
        End If    Set picStream = Nothing
        GdipDisposeImage lBitmap
        GdiplusShutdown lngGdipToken
    End Function
    测试代码:'示例
    Private Sub Command1_Click()
        Dim s As IStream
        Set s = PictureToStream(Me.Picture1.Picture)
        Set Me.Picture2.Picture = StreamToPicture(s)
    End Sub
    不知楼主是否看的明白,可再回复。
      

  3.   

    通过网络传输时数据被自动分包了,一个 PropertyBag.Contents 会有多次 DataArrival 事件触发,你仅仅将第1个包的字节数组赋值给 PropertyBag.Contents 当然会出错了。
    需要自己作一下缓存:
    a)发送端首先发送一个 Long 值表示字节数组的长度,然后再发送字节数组。
    b)接受端
     1)先接收到总长的 Long 值,然后定义一个总长的模块级缓存数组,
     2)以后每次收到的数据都复制到缓存数组中
     3)一直到缓存数组被填满,才用 PropertyBag 转换成图片进行显示。