Click here to Skip to main content
15,884,693 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
Hey again

I have made a program that turns an image into a base64 string and sends via UDP.
the problem is that i get an error when the base64 is too large
How do you compress this on the host side and then decompress back into a base64 string on the client side?

Help is appreciated.
Posted
Comments
Sergey Alexandrovich Kryukov 18-Mar-13 14:07pm    
Compressing and base64 have nothing in common. Chances are, the problem is not in base64, but in your use of it. Have you been able to reproduce the problem under debugger?
Can you make a code sample? We cannot see where things go wrong right now.
—SA
[no name] 18-Mar-13 14:21pm    
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim bounds As Rectangle
Dim screenshot As System.Drawing.Bitmap
Dim graph As Graphics
bounds = Screen.PrimaryScreen.Bounds
screenshot = New System.Drawing.Bitmap(bounds.Width, bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
graph = Graphics.FromImage(screenshot)
graph.CopyFromScreen(bounds.X, bounds.Y, 0, 0, bounds.Size, CopyPixelOperation.SourceCopy)
sending.Image = screenshot
Dim n As New Bitmap(100, 100, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
n = screenshot
toSend = ImageToBase64String(n, Imaging.ImageFormat.Jpeg)
go()
End Sub

n=screenshot is used as screenshot is too large, but so is n by the looks of it :)
Sergey Alexandrovich Kryukov 18-Mar-13 15:50pm    
And where the exception is thrown, what line? Exception information, please.
And please reply to my comment, otherwise I won't get a notification.
—SA
Sergey Alexandrovich Kryukov 18-Mar-13 17:07pm    
Why UDP, not TCP?
If you have problems with uncompressed data, you will have the same on compressed, only at larger volumes.
—SA
[no name] 19-Mar-13 12:10pm    
the exception line is where it says go() as that is where the base64 is sent.
As the base64 is too large, it cannot go through the network.

If you want to send images over network and you don't want TCP because of it's overhead or other limitations, you can use of course UDP. But: UDP is not reliable, and as you noticed, you might encounter several problems if you want to send large files (that need to remain consistent). Theoretically, UDP is not for that. But modern networks might bring you the stability you can benefit from, and achieve better performance than TCP. But you have to implement a layer above UDP, a protocol. If you don't want to think about a new one, look at RUDP[^]. Well, you could implement for yourself, but you don't have the knowledge. So I suggest you use this one: http://rudp.codeplex.com/[^].
Please note, that compressing the stream won't help you if you try to send already compressed image files, quite indifferent of it's original compression method. Base64 encoding an image and compressing it with an other method will in general enlarge the result. Forget this idea.
 
Share this answer
 
Comments
[no name] 22-Mar-13 13:32pm    
where did you see c.net or c# in my tags?
i thought i was using visual basic. :)
Zoltán Zörgő 22-Mar-13 14:04pm    
Where do you see c# in my answer? But actually you can do the same in vb.net as in c#, thus if i would have given you a c# reference (which I have not - the stuff on codeplex link is a general .net library, thus does not matter from which language you come from) - it would have not been at the level of the problem you are facing.
Why are you converting an image to Base64 in the first place?? Surely it can't be to think you'll get less data to send?? You're actually making MORE data to send, not less by doing this conversion. A screenshot at 1280x1024 results in just over 5.12MB of data. The Base64 string of this data is over 6.8MB.

Base64 was written to send binary data acrossed links and systems designed to carry textual traffic only. UDP over Ethernet is not such a transport. It'll handle binary data just fine on its own. So, what are you sending this image to and why does it have to be Base64??
 
Share this answer
 
Comments
[no name] 19-Mar-13 12:11pm    
i am translating the image to base64 string as my code sends strings (convenient).
what other types of string can images be turned into and back again, but using less space?
i tried hex but i found that confusing
Sergey Alexandrovich Kryukov 19-Mar-13 12:18pm    
Convenient? It is not. You comment simply makes no sense. Just use simple logic.
—SA
Sergey Alexandrovich Kryukov 19-Mar-13 12:19pm    
There is not such thing as "hex" (unless you are talking about text representation)! Confused? I'm starting to think that you are not ready for such things, by far.
You first need to learn the very basics of programming, starting with presentation of numbers in memory, strings, etc.
—SA
Dave Kreskowiak 19-Mar-13 13:04pm    
Sending an array of bytes, I'm guessing what you call "hex" (no such thing!), is easier than sending a string.

There is no way to represent binary data as a string in less space than the original data.
Sergey Alexandrovich Kryukov 19-Mar-13 12:17pm    
Exactly, a 5.
—SA
Hello,

How about using System.IO.Compression.GZipStream class. The example of using this class can be found here[^] in MSDN library. There is one more example available here[^].

Regards,
 
Share this answer
 
Comments
[no name] 18-Mar-13 14:25pm    
how do i use a bitmap instead of a filepath?
Prasad Khandekar 18-Mar-13 14:58pm    
If it's Web App then you can not. There is a specification for sending inline image data (base64 encoded) but now all browsers implement it.
[no name] 18-Mar-13 15:17pm    
it's not a web app, just a .exe.
i just want to take a screenshot and send it, but without saving it first (just put into bitmap)
how to compress the base64 from the bitmap?
Prasad Khandekar 18-Mar-13 15:46pm    
You can use Save(Stream, ImageFormat) method of bitmap where Stream will be a Byte array stream. You will then convert this byte array to a base64 encoded string and finally use this string with GZipStream.
You can turn a bitmap into an array of bytes with this:
' You can use your own bitmap object.  This one is just for illustration.
Dim myBitmap As New Bitmap(1280, 1024, PixelFormat.Format32bppArgb)

' Create a Rectangle object the size of the entire bitmap.
Dim rect As New Rectangle(0, 0, myBitmap.Width, myBitmap.Height)

' LockBits on the bitmap so we can get at the image data.
Dim imageData As BitmapData = myBitmap.LockBits(rect, ImageLockMode.ReadOnly, myBitmap.PixelFormat)

' Get a pointer to the first byte of the image data.
Dim ptrByte0 As IntPtr = imageData.Scan0

' Get the number of bytes used to store the bitmap data.
Dim numBytes As Integer = imageData.Stride * imageData.Height

' Create an array to hold all the bytes comtaining the image data.
Dim byteData(numBytes - 1) As Byte

' Make a copy of the image data to our array.
Marshal.Copy(ptrByte0, byteData, 0, numBytes)

' Release the lock.
myBitmap.UnlockBits(imageData)

Now you've got an array containing all the image data. What you do with this is up to you, but now it's in a format (an array) that can be sent using a UdpClient.
 
Share this answer
 
Comments
[no name] 27-Mar-13 14:26pm    
i tried your solution, but, firstly, my code sends a string and receives a string.
how can i do this with this code?
and the error of "A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself" still happens

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900