Duda envio de imagen por winsock

Iniciado por azul27, 19 Octubre 2010, 21:36 PM

0 Miembros y 1 Visitante están viendo este tema.

azul27

Buenas ! tengo una dudilla... estoy construllendo un screen capture,
desde el servidor consigo hacer la imagen de pantalla todo perfecto, y la guardo
como .jpg en la misma carpeta vale.

Luego, la abro en binario, lo almaceno en una string y lo envio por winsock
al cliente, en el cliente capto los datos, abro un archivo nuevo en binary
y meto los datos ahí, guardo como jpg y tal.

Que pasa, que la imagen se vé una esquina de la imagen real, no se vé
bien, sin envargo sé que el servidor toma la foto bien, porque la guardo también
y veo que la foto es perfecta, el problema tiene que estar al transmitir la información.. y bueno, que no se que hacer para que se envie bien la data..

Que Dicen? :D

Psyke1


azul27

Como sabemos, foto es un módulo de clase que anda por ahí !


Dim FileSize As String

foto.SetSamplingFrequencies 2, 2, 2, 2, 2, 2
foto.Quality = 100
foto.SampleScreen
foto.SaveFile ("try1.jpg")
'importante#

Dim av3 As String

Open App.Path & "\xD.jpg" For Binary As 1 ' la propia foto q creamos
av3 = Space(LOF(1))
Get 1, , av3
Close 1


'fotofil = FiletoString(App.Path & "\xD.jpg") ' prueba 22


WS.SendData "scc" & "\" & av3

Sleep (1000)

Psyke1

No envies un String. Utiliza un array de Bytes mejor.
Te dejo un ejemplo, hay millares por ahi.
Ver ejemplo Envio de archivos Winsock
Investiga un poco que este tema esta ya muy "sobado"... :laugh:

DoEvents! :P

azul27

valeeeee gracias, ahora investigaré !!!

Alguna idea para hacerlo más efectivo, y optamizar el traspaso de info ?



PD: Graaaaaaaaaaaaaaaaaaaaaaaaaaaaacias.  :D

BlackZeroX

#5
.
Usa un protocolo con espera ( Delay limitante de protocolo )

Como saludar:

Cliente: TemandoIMG,Pesa:1024kb's
Server:  Ok_Enviame desde el Byte 1
Cliente: Envia el array de bytes
Server Recive
Cliente: Ok Ya estan los 1024kb's completos.
Cliente: Fin
Server: MostrarImagen En Streeming:


OJO MODIFICA ESA CLASE
para que obtengas directamente lo que son los bytes a escribir y desbialos para asi mandarlos, me parece que ocupas cJPG o algo asi se llama la clase... esto para que NUNCA TOQUES EL HDC y sea RAPIDO

Para mostrar una imagen en Streeming desde un Array de bytes():

Código (Vb) [Seleccionar]


Option Explicit

Private Type GUID                               '   //  16 bytes (128 bits)
 dwData1                   As Long             '   //  4 bytes
 wData2                    As Integer          '   //  2 bytes
 wData3                    As Integer          '   //  2 bytes
 abData4(7)                As Byte             '   //  8 bytes, zero based
End Type

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpsz As Any, pclsid As GUID) As Long
Private Declare Function OleLoadPicture Lib "olepro32" (pStream As Any, ByVal lSize As Long, ByVal fRunmode As Boolean, riid As GUID, ppvObj As Any) As Long
Private Declare Function CreateStreamOnHGlobal Lib "ole32" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As Boolean, ppstm As Any) As Long

Private Const GMEM_MOVEABLE& = &H2
Private Const S_OK& = &H0

Public Function Array_LoadImage(ImageBytes() As Byte) As StdPicture
Dim nBytes                                  As Long
Dim hMem                                    As Long
Dim lpMem                                   As Long
Dim oStream                                 As IUnknown
Dim oPicture                                As IPicture
Dim IID_IPicture                            As GUID
Const sIID_IPicture                         As String = "{7BF80980-BF32-101A-8BBB-00AA00300CAB}"

  If (Not ImageBytes) = -1 Then Exit Function
  nBytes = UBound(ImageBytes) - LBound(ImageBytes)
  If LBound(ImageBytes) = 0 Then nBytes = nBytes + 1
  hMem = GlobalAlloc(GMEM_MOVEABLE, nBytes)
  If hMem > 0 Then
     lpMem = GlobalLock(hMem)
     If lpMem > 0 Then
        Call CopyMemory(ByVal lpMem, ImageBytes(LBound(ImageBytes)), nBytes)
        Call GlobalUnlock(hMem)
        If (CreateStreamOnHGlobal(hMem, False, oStream) = S_OK) Then
           If (CLSIDFromString(StrPtr(sIID_IPicture), IID_IPicture) = S_OK) Then
              Call OleLoadPicture(ByVal ObjPtr(oStream), nBytes, False, IID_IPicture, oPicture)
              Set Array_LoadImage = oPicture
           End If
        End If
     End If
     Call GlobalFree(hMem)
  End If
End Function



Dulce Infierno Lunar!¡.
The Dark Shadow is my passion.

azul27

Pues al principio muy bien, pero acabé dejandolo.. me es imposible de entender..
no hay alguna manera de enviar el archivo como un paquete simplemente.. así sería
mucho más facil :S es que no entiendo lo de enviar primero lo que pesa, y luego los bytes a bytes nose no entiendo :-(

yovaninu

Este foro de Basic ya se ha vuelto de 'pros' ya es raro ver estos temas, ademas esos 'pros' te van a ayudar como si tu tambien fuera otro 'pro' (pro=profesional).

Hace un buen tiempo que el foro es solo para 'ellos' pues solo ellos se entienden, si revisas el foro hay codigos en donde ya ni se explica cual es su uso y su ventaja, solo postean y su proseria lo intepreta todo. Ya me imagino la mosqueada que se viene por este comentario en fin. (Donde estara xenon fulano, esos si eran verdaderos... Enseñaban)
:(

A ver si te sirve mi ayuda un poco larga pero es la comun:

Para enviar un archivo lo tienes que hacer siguiendo un cierto orden: (asumiendo que es el Servidor quien envia al Cliente)
- Primero: El Servidor le envia al cliente un mensaje junto al tamaño del archivo que va a enviar. Por ejemplo Servidor.SendData "e_archivo" & Len(Data)
Donde: "e_archivo" es un mensaje cualquiera y "Data" es el String en donde sacaste el archivo que vas a enviar.

- Segundo: El cliente recibe ese mensaje y guarda en una variable el tamaño que el servidor le va a enviar. Esto es necesario ya que el cliente debe saber cuanto tiene que recibir del Servidor. Hay otras formas pero lo basico funciona de esa forma.
Asumamos que ese tamaño lo guardaste en la Variable TAMANIO

- Tercero: Hecho eso, el Cliente le envia un mensaje al Servidor indicandole que proceda a enviar el archivo pues con el tamaño ya tiene lo suficiente para recibirlo.
Ej:

Cliente.SendData "envialo"
'aqui debes activar un interruptor para que el cliente reciba correctamente el archivo
Viene_Archivo=True

'ademas debes inicializar una variable String en donde iras acumulando lo que el servidor este enviando
Archivo=""

- Cuarto: El servidor recibe ese mensaje e inicia el envio del archivo
Ej:

Servidor. SendData Data;

-Quinto: El CLiente empezara a recibir el archivo en la variable 'Archivo'
Lo recibira mas o menos asi

En el Data Arrival de tu CLiente

If (Len(Archivo)==TAMANIO)
  "Archivo Recibido OK"
Else
  Cliente.GetData Datos 'En datos vas acumulando lo que el servidor va enviando
  Archivo=Archivo & Datos
End If


Cuando el Len(Archivo) sea igual a TAMANIO entonces quiere decir que el servidor a enviado el archivo correctamente.

Saludos

Psyke1

#8
.

Cita de: yovaninu en 22 Octubre 2010, 16:32 PM
Este foro de Basic ya se ha vuelto de 'pros' ya es raro ver estos temas, ademas esos 'pros' te van a ayudar como si tu tambien fuera otro 'pro' (pro=profesional).

Hace un buen tiempo que el foro es solo para 'ellos' pues solo ellos se entienden, si revisas el foro hay codigos en donde ya ni se explica cual es su uso y su ventaja, solo postean y su proseria lo intepreta todo. Ya me imagino la mosqueada que se viene por este comentario en fin. (Donde estara xenon fulano, esos si eran verdaderos... Enseñaban)
:(

...

:¬¬
Yo si me molesto por aprender algo pregunto, pero antes de preguntar busco y me informo, cosa que azul27 está claro que no a hecho. (El 1er enlace de Google trae un ejemplo commentado [entre muchisimas mas referencias] ).  :silbar:
Creo que en este foro los usuarios que preguntan con sentido salen beneficiados, generalmente las cosas se explican bastante bien creo yo. :)

De paso aprobecho para decir :

CitarDonde: "e_archivo" es un mensaje cualquiera y "Data" es el String en donde sacaste el archivo que vas a enviar.
Mejor si se usa api GetFileSize o la función FileLen, quedamos en que es más combeniente usar un array de Bytes!
En mi opinión te molestas en explicar una cosa que esta ya mas vista que un tebeo y encima no de la mejor forma. :-\
Tiene un ejemplo mucho mejor en el primer enlace que puse.
Eso mas  la ayuda de BlackZer0x para mostrar una imagen en Streeming desde un array de Bytes.

DoEvents! :P


BlackZeroX

.
Eso de pros no lo creo, no atacare solo dire miren los primeros Post de Mr -Frogs ( Alias *Spyke*)... na ha pasado michu desde esos post y ya es Wiki ademas de que si no entiende algo lo busca eso me consta!¡.
....

Volviendo al tema, si de hecho debes hacer un protocolo para saber cuando se acabo la captura de la pantalla o de lo contrario el programa no sabra cuando termina de resivir algo, es decir puede inclusive otros paquetes de datos interpretarlos como los datos de un archivo anteriormente enviado, o sencillamente puede que NUNca cierre o cree un archivo nuevo es por eso del protocolo, no es que se un foro para Pros como dicen por hay, yo diria que es un foro para quien desea aprender si es que realmente desea hacerlo, es decir alguien que o lo dea no investiga y quiere todo en Bandeja de Oro.

Dulce Lunas!¡.
.
The Dark Shadow is my passion.