send Image over network (netmaestro)

Just starting out? Need help? Post your questions and find answers here.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Code: Select all

;**************************************************************** 
; Program:             Send/Receive image over network Demo 
; Author:              netmaestro 
; Date:                March 23, 2007 
; Target OS:           Microsoft Windows All 
; Target Compiler:     PureBasic 4.xx 
; License:             Free, unrestricted, credit appreciated 
;                      but not required 
;**************************************************************** 

; *************************************************** 
;          Off-Topic: Image to test with 
; *************************************************** 
UseJPEGImageDecoder() 

ProcedureDLL Read_File(file.s)  
  #INTERNET_FLAG_RELOAD = $80000000 
  Bytes.l = 0 
  *html  = AllocateMemory(50000) 
  hInet.l = InternetOpen_("lloydsplace.com", 1, #Null, #Null, 0) 
  If hInet 
    hURL.l  = InternetOpenUrl_(hInet, file, #Null, 0, #INTERNET_FLAG_RELOAD, 0) 
    If hURL 
      If InternetReadFile_(hURL, *html, 50000, @Bytes) 
        hBmp = CatchImage(#PB_Any,*html, bytes) 
        InternetCloseHandle_(hURL) 
      Else 
        ProcedureReturn 0 
      EndIf 
    Else 
      ProcedureReturn 0 
    EndIf    
    InternetCloseHandle_(hInet) 
  Else 
    ProcedureReturn 0 
  EndIf 
  ProcedureReturn hBmp 
EndProcedure 

hBmp = Read_File("http://lloydsplace.com/kylie-minogue.jpg") 

If IsImage(hBmp) 
  MessageRequester("", "Image is downloaded, click to test image prep/reconstitution",$C0) 
Else 
  MessageRequester("oops", "problem downloading the image - try with something else", $C0) 
  End
EndIf 

;************************************************************** 
;   End of Off-Topic Section - Start paying attention now 
;************************************************************** 

Global BmiInfo.BITMAPINFOHEADER, bmpWidth.w, bmpHeight.w 

Procedure Get24BitColors(pBitmap) 
  GetObject_(pBitmap, SizeOf(BITMAP), @bmp.BITMAP) 
  bytesperrow = 4*((3*bmpWidth+3)/4) 
  *pPixels = AllocateMemory(bytesperrow*bmpHeight) 
  hDC = GetWindowDC_(#Null) 
  iRes = GetDIBits_(hDC, pBitmap, 0, bmpHeight, *pPixels, @bmiInfo, #DIB_RGB_COLORS) 
  ReleaseDC_(#Null, hDC) 
  ProcedureReturn *pPixels 
EndProcedure 


;*************** Prepare image for sending ******************** 

GetObject_(ImageID(hBmp), SizeOf(BITMAP), @Bmp.BITMAP) 

bmpWidth  = Bmp\bmWidth 
bmpHeight = Bmp\bmHeight 

With BmiInfo 
  \biSize         = SizeOf(BITMAPINFOHEADER) 
  \biWidth        = bmpWidth 
  \biHeight       = bmpHeight 
  \biPlanes       = 1 
  \biBitCount     = 24 
  \biCompression  = #BI_RGB  
EndWith 

*_24bitColors = Get24BitColors(ImageID(hBmp)) 

ImageSize = SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER) +  MemorySize(*_24bitColors) 

*rawimage = AllocateMemory(ImageSize) 
*fileheader.BITMAPFILEHEADER = *rawimage 
*header.BITMAPINFOHEADER = *rawimage + SizeOf(BITMAPFILEHEADER) 

With *fileheader 
  \bfType = 19778 ; word containing 2 bytes, 'BM' for 'BIT' 'MAP' ;) 
  \bfSize = ImageSize 
  \bfOffBits = SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER) 
EndWith 

CopyMemory(@BmiInfo, *header, SizeOf(BITMAPINFOHEADER)) 

CopyMemory(*_24bitColors, *rawimage + SizeOf(BITMAPFILEHEADER) + SizeOf(BITMAPINFOHEADER), MemorySize(*_24bitColors)) 
*PackedImage = AllocateMemory(ImageSize+8) 
PackSize = PackMemory(*rawimage, *PackedImage, ImageSize) 

;******** All ready to go now, send *PackedImage data and ImageSize ********* 

; Send image from *PackedImage 
; Send ImageSize 
; [..] 
; Receive image to *PackedImage 
; Receive imagesize to ImageSize.l 

; ********* Image is here now, unpack it ************ 
*UnPacked = AllocateMemory(ImageSize) 
UnpackMemory(*PackedImage, *UnPacked) 

;********** How'd we do? Catch and display ********** 

CatchImage(0, *unpacked) 

OpenWindow(0,0,0,ImageWidth(0),ImageHeight(0),"Reconstituted Image",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 

ImageGadget(0,0,0,0,0,ImageID(0)) 
Repeat:Until WaitWindowEvent() = #WM_CLOSE 
Last edited by netmaestro on Mon Dec 26, 2011 5:36 am, edited 3 times in total.
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Nice.

Practically identical to my own.

If I'd known named pipes were using disk space, I'd have gone straight for this method in my own app. Anyhow, I've now removed the pipes and saved the image directly into my own file along with other images and fonts. It works well and of course it will run on win 98.

(Are the forums playing up again; it's taken me ages to be able to post this?)
I may look like a mule, but I'm not a complete ass.
Brice Manuel

Post by Brice Manuel »

srod wrote:(Are the forums playing up again; it's taken me ages to be able to post this?)
Buggier than Bamberware
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

I personally think someone's attacking the forum server with some kind of DOS attack, as the difficulties seem to mimic an overloaded server, even though usage is light.
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

:)

@netmaestro: looking again at your code, I'm not sure you're allocating enough memory for the GetDIBits. This function, when asked to create a 24 bit DIB, will pad each row out so that it is a multiple of 4 bytes. I think that some images might cause a memory problem with your code.

I had this with my code until I adjusted it.

Unless I've misinterpreted your code. :)
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

*pPixels = AllocateMemory(bmpWidth*bmpHeight*3)

So, what should this be then? bmpWidth*bmpHeight*4? Can you provide a picture that makes my code fail, as all my tests are OK? If it isn't right, I certainly would like to fix it.
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I understand now. You're actually reducing the width of the bitmap to make it a multiple of 4. This of course means that you might be losing a few columns of pixels at the far right of the image.

I've tested with a couple of images and that indeed seems to be what is happening.

Instead of adjusting the width of the bitmap, you should increase the amount of memory allocated to give each row a multiple of 4 bytes.

Code: Select all

Procedure Get24BitColors(pBitmap) 
;  GetObject_(pBitmap, SizeOf(BITMAP), @bmp.BITMAP) 
  bytesperrow = 4*((3*bmpWidth+3)/4)
  *pPixels = AllocateMemory(bytesperrow*bmpHeight) 
  hDC = GetWindowDC_(#Null) 
  iRes = GetDIBits_(hDC, pBitmap, 0, bmpHeight, *pPixels, @bmiInfo, #DIB_RGB_COLORS) 
  ReleaseDC_(#Null, hDC) 
  ProcedureReturn *pPixels 
EndProcedure 
You will also need to remove the line

Code: Select all

bmpWidth - (bmpWidth%4)
(I love the image by the way!! Pwhooarrrrr...)
I may look like a mule, but I'm not a complete ass.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Down, boy!

Ok, as I recall now I had a reason for not caring about the last (max. 3) pixels getting chopped off the right side of the image back when I wrote that procedure. But your solution is better, so I've amended my code to reflect the changes. I'm not 100% sure there isn't a pixel gone from the right side of that photo though, so I'm going to have to stare at it over and over and over..
BERESHEIT
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

:D

Every pixel counts with this image!

Now where was I before being so rudely interrupted?

Oh yes,... phwooooaaaaarrrr.....

(p.s. I wouldn't show that image to fangles; he'll probably explode!)
I may look like a mule, but I'm not a complete ass.
Tomio
Enthusiast
Enthusiast
Posts: 291
Joined: Sun Apr 27, 2003 4:54 pm
Location: Germany

Post by Tomio »

A note only. Nothing new.

It's not good to be fixated to much on one point and ignore the rest.
After having considered the situation once more, it became clear (to me) that it's not worth to save disk save/load time.

This is in short and roughly the time situation:
a)CopyDesktopToImage 0.?%
b)DoSomeThing+Compress 1%
c)SendOverNetwork 98%
e)DoSomeThing+Decompress 1%
f)CreateImage+Display 0%

b)+c) depend stronly on bandwidth and compression, but however it is done, the time for Saveimage/LoadImage can be neglected.

And: the faster the host the more extreme the ratios are.

Though it would look smarter to send the image straight away (after compressing!!) from memory through the net, there was no noticeable time saving doing this.

By the way, I did some time measurements.
I did it on one of those small Win98 clients which are to run the tool.
Perhaps you are interested:
The task was: Grab Screen to Image --> SaveImage --> LoadImage
All timevalues are the mean of 20 runs.

GrabScreenTo Image == 1.32 sec
SaveImage+LoadImage == 0.24 sec BMP == 2359350 Bytes
SaveImage+LoadImage == 2.69 sec JPEG == 162215
SaveImage+LoadImage == 2.8 PackMemory() == 47338 (!)

PackMemory() was with factor=3 (4 took already too long).

So, for me it's obvious: PackMemory + diskfile.

.../tomio
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8452
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

You're most welcome! Looks like you've got a good handle on your project, good luck with it :wink:
BERESHEIT
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Brice Manuel wrote:Buggier than Bamberware
lol! :lol: I guess he is still king of the bugs.
--Kale

Image
Post Reply