Seite 1 von 2

Screenshot direkt über Memory senden

Verfasst: 26.12.2012 14:47
von Moxl
Hallo,

ich hab folgendes vor,
ich möchte bei meinem client ein screenshot machen und der screenshot soll direkt in den memory geschrieben und dann direkt mit sendnetworkdata() versendet werden.
vom server soll das dann empfangen und dann in eine datei geschrieben werden.

Das hab ich zurzeit aber es funktioniert irgendwie nicht:

server:

Code: Alles auswählen

InitNetwork()
If  CreateNetworkServer(0, 6700)<>0
  OpenWindow(0, 0, 0, 200, 20, "", #PB_Window_BorderLess)
  ProgressBarGadget(0, 0, 0, 200, 20, 0, 0)
  Repeat
    Delay(10)
    windowevent=WindowEvent()
    serverevent=NetworkServerEvent()
    If  serverevent=#PB_NetworkEvent_Connect
      Debug "Client connected"
    EndIf
    If  serverevent=#PB_NetworkEvent_Data
      Debug "Daten empfangen"
      result = ReceiveNetworkData(EventClient(), @Size, 4)
      Debug "Empfangene Bytes (Größe der Long (müssten 4 sein)): "+Str(result)
      Debug "Empfangene Bytes (Größe des Screenshots): "+Str(Size)
      If result = 4 And Size > 0
        SetGadgetAttribute(0, #PB_ProgressBar_Maximum, Size)
        ;Allokiere Speicher in dieser Größe
         *MemBuffer = AllocateMemory(Size)
         errorcounter = 0 
         ReceivedBytes = 0
         Repeat
           SetGadgetState(0, ReceivedBytes)
           ;Speicher die Anzahl der geladenen Bytes                                 {noch zu laden}
          result = ReceiveNetworkData(EventClient(), *MemBuffer + ReceivedBytes, Size - ReceivedBytes)
          If result = -1
           Delay(1) 
           errorcounter + 1
          Else
           ReceivedBytes + result
           errorcounter = 0
          EndIf
        Until ReceivedBytes = Size Or errorcounter > 6000 ; Abbruch nach 6 Sekunden
      EndIf
      If Size > 0 And ReceivedBytes = Size
        screenshot$=GetHomeDirectory()+"Screenshot "+FormatDate("%hh-%ii-%ss", Date())+".bmp"
        If  CreateFile(0, screenshot$)
          WriteData(0, *MemBuffer, Size)
          CloseFile(0)
          FreeMemory(*MemBuffer)
        Else
          Debug "datei konnte nicht erstellt werden"
        EndIf
      Else
        Debug "screenshot konnte nicht heruntergeladen werden"
      EndIf
    EndIf
    If  serverevent=#PB_NetworkEvent_Disconnect
      Debug "Client disconnected"
    EndIf
  Until windowevent=#PB_Event_CloseWindow
Else
  Debug "server konnte nicht erstellt werden"
EndIf
client:

Code: Alles auswählen

Procedure MakeDesktopScreenshot(ImageNr,x,y,Width,Height)
   hImage = CreateImage(ImageNr,Width,Height) 
   hDC    = StartDrawing(ImageOutput(ImageNr)) 
   DeskDC = GetDC_(GetDesktopWindow_()) 
      BitBlt_(hDC,0,0,Width,Height,DeskDC,x,y,#SRCCOPY) 
   StopDrawing() 
   ReleaseDC_(GetDesktopWindow_(),DeskDC) 
   ProcedureReturn hImage 
EndProcedure
Procedure CopyImageToMem(Img.l, mem.l)
  Protected bmi.BITMAPINFO
  Protected w.l, h.l, hBmp.l, hDC.l

  w = ImageWidth(Img)
  h = ImageHeight(Img)
  hBmp = ImageID(Img)
 
  bmi\bmiHeader\biSize        = SizeOf(BITMAPINFOHEADER)
  bmi\bmiHeader\biWidth       =  w
  bmi\bmiHeader\biHeight      = -h
  bmi\bmiHeader\biPlanes      =  1
  bmi\bmiHeader\biBitCount    = 32
  bmi\bmiHeader\biCompression = #BI_RGB
 
  hDC  = StartDrawing( ImageOutput(Img) )
  If GetDIBits_(hDC, hBmp, 0, h, mem, bmi, #DIB_RGB_COLORS)
    StopDrawing()
    ProcedureReturn #True
  Else
    StopDrawing()
    ProcedureReturn #False
  EndIf
EndProcedure

InitNetwork()
verbindung=OpenNetworkConnection("localhost", 6700)
If  verbindung<>0
  ExamineDesktops()
  MakeDesktopScreenshot(0, 0, 0, DesktopWidth(0), DesktopHeight(0))
  ResizeImage(0, 800, 600)
  *mem=AllocateMemory(ImageWidth(0)*ImageHeight(0)*4)
  If  CopyImageToMem(0, *mem)=0
    Debug "copy image to mem fail"
  Else
    Size.l=MemorySize(*mem)
    Debug "Größe vom Reservierten Speicher: "+Str(Size)
    x=SendNetworkData(verbindung, @Size, 4)
    Debug "Gesendete Bytes (Größe der Long (müssten 4 sein)): "+Str(x)
    y=SendNetworkData(verbindung, *mem, Size)
    Debug "Gesendete Bytes (Größe des Screenshots): "+Str(y)
    FreeMemory(*mem)
  EndIf
Else
  Debug "verbindung fehlgeschlagen"
EndIf
ich komm einfach net weiter und finde den fehler nich... :bluescreen:

danke schonmal im vorraus :allright:

Re: Screenshot direkt über Memory senden

Verfasst: 26.12.2012 17:45
von STARGÅTE
Was funktioniert denn nicht?

Du kannst ja auch erst mal selber auf Fehlersuche gehen:
  • Wird eine Verbindung aufgebaut?
  • Wird ein Screenshot gemacht?
  • Wird ein gültiges Image erzeugt?
  • Funktioniert die Umwandlung von Image zu Memory?
  • Würde das Bild auf dem selben PC wieder richtig erstellt werden?

Re: Screenshot direkt über Memory senden

Verfasst: 26.12.2012 20:35
von Moxl
hab ich doch :o

wird alles durch debug angezeigt... und die image wird auch auf dem selben pc mittels saveimage() erzeugt... nur wenn ich das image dort erzeuge hat die bilddatei weniger mb als die datei die man dann geschickt bekommt :|

also schätze ma es liegt am speicherplatz reservieren das es vllt die falsche größe ist oder so... aber wenn ich weniger mache dann klappts mitm copyimagetomem nicht

Re: Screenshot direkt über Memory senden

Verfasst: 26.12.2012 21:43
von STARGÅTE
Ich führe ja den Code nicht selber aus, deswegen sehe ich keine Debug-Ausgabe, denn das Problem hast du ja festgestellt.

Und das Problem hast du ja nun erkannt: Es kommt eine falsche Größe an.

Du sendest über das Netzwerk nur: ImageWidth(0)*ImageHeight(0)*4 Bytes, also die reinen Pixel.
Und am Ende speicherst du in deiner Datei auch nur die Pixel.
Zu einem Bild gehört aber noch ein Header, mit Infos zum Format usw. das speicherst du bei SaveImage, aber nicht bei deinem eigene CreateFile.

Also: Entweder kompletten Bild senden (mit Header), oder einfach die gesendeten Pixel in ein Image schreiben und dann das Image speichern.

Re: Screenshot direkt über Memory senden

Verfasst: 26.12.2012 22:00
von Moxl
hm achso... ma so ne nebenfrage.. warum macht man eigentlich imagewidth*imageheight*4? also warum mal 4? hab das nur aus nem forum kopiert deswegen frag ich..

und ich glaub das mit dem pixel in ne image schreiben und diese speichern is ne gute idee.. meinst du du kannst mir mal kurz n beispiel machen wie das funzt? :/ kenn mich mit images und drawing gar nich aus :/

Re: Screenshot direkt über Memory senden

Verfasst: 27.12.2012 00:55
von jojo1541
Du machst Breite*Höhe*Farbtiefe, weil ein Bild dann doch noch Speicherplatz für seine Pixel braucht.

Je nach Farbtiefe sind das eben 4bpp = 16 Farben, 8bpp = 256 Farben, 16bpp = 65k, 24bpp = 16Mille und 32bpp = 16 Mille + Alpha.
bpp (Bits per Pixel)

Da 32 Bits nunmal 4 Byte sind, musst du eben mal 4 nehmen. :wink:

Re: Screenshot direkt über Memory senden

Verfasst: 27.12.2012 01:01
von Moxl
ahhh ok verstehe ;)

jetzt is nur noch die frage mit den pixel in ein image schreiben offen :D

Re: Screenshot direkt über Memory senden

Verfasst: 27.12.2012 01:06
von jojo1541
Naja, Stargate hat es ja eigentlich schon gesagt.

Du sendest nur das Bild selber, nicht aber den Header.

Entweder du sendest einen Header mit und erstellst dann via CreateFile() oder du schreibst die Pixel aus dem Speicher in ein von dir via CreateImage() erstelltes Bild und speicherst dieses dann mit SaveImage().

Re: Screenshot direkt über Memory senden

Verfasst: 27.12.2012 01:21
von Moxl
genau das habe ich ja vor^^ aber nach
CreateImage(0)
startdrawing(imageoutput(0))

weiß ich nichmehr weiter x)

Re: Screenshot direkt über Memory senden

Verfasst: 27.12.2012 01:30
von Moxl
ok ich habs :)

gibt n befehl im codearchiv: CopyMemToImage()