Page 1 of 2
Posted: Fri Mar 23, 2007 3:29 pm
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
Posted: Fri Mar 23, 2007 4:50 pm
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?)
Posted: Fri Mar 23, 2007 4:53 pm
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
Posted: Fri Mar 23, 2007 4:58 pm
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.
Posted: Fri Mar 23, 2007 5:03 pm
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.

Posted: Fri Mar 23, 2007 5:19 pm
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.
Posted: Fri Mar 23, 2007 5:51 pm
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
(I love the image by the way!! Pwhooarrrrr...)
Posted: Fri Mar 23, 2007 6:06 pm
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..
Posted: Fri Mar 23, 2007 6:11 pm
by srod
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!)
Posted: Sat Mar 24, 2007 11:58 am
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
Posted: Sat Mar 24, 2007 12:14 pm
by netmaestro
You're most welcome! Looks like you've got a good handle on your project, good luck with it

Posted: Sat Mar 24, 2007 1:09 pm
by Kale
Brice Manuel wrote:Buggier than Bamberware
lol!

I guess he is still king of the bugs.