Click here to Skip to main content
12,997,210 members (76,283 online)
Rate this:
Please Sign up or sign in to vote.
See more: , +
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 18-Mar-13 7:33am
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.
Rixterz123 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)
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.
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.
Rixterz123 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.
Sergey Alexandrovich Kryukov 19-Mar-13 12:16pm
I have no idea why do you use base64 at all. It's only used for text-only standards, but with sockets you can sent anything.
Throw out this base64, it makes no sense at all. Compress the original data.
And you still did not answer my question.
Rixterz123 19-Mar-13 12:24pm
i used UDP because that was the code that i found, i did not type it myself.
So, as i use go(), it takes a string parameter, translates it to bytes, and it goes off to the specified IP.
The only way is to make a bitmap --> string.
How can i do this with a large bitmap, turn to a type of string, and then compress the string, send, and decompress on the other end?
Rate this: bad
Please Sign up or sign in to vote.

Solution 4

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:[^].
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.
Rixterz123 22-Mar-13 13:32pm
where did you see 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 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.
Rate this: bad
Please Sign up or sign in to vote.

Solution 2

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??
Rixterz123 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.
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.
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.
Rixterz123 19-Mar-13 12:31pm
so what do i turn the bitmap into so it can be used in this?:

Private Const port As Integer = 54545
Private Const broadcastAddress As String = ""
Private sendingClient As UdpClient
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub InitializeSender()
sendingClient = New UdpClient(broadcastAddress, port)
sendingClient.EnableBroadcast = True
End Sub
public toSend As String
Dim data() As Byte
Public Shared Sub go() = Encoding.ASCII.GetBytes(Form1.toSend)
End Sub

You call it with

Dave Kreskowiak 19-Mar-13 13:06pm
First, you don't use that code to send binary data. You're just trying to adapt something you found on the 'Net to some need you have without knowing exactly how it works. Bad idea. You're not learning anything by doing that. You're just funbling around in the dark until you stumble upon a solution that might work.

What are you trying to do with all of this?? Why are you sending a screen shot to another machine?? Are you trying to make your own Remote Desktop app??
Rixterz123 22-Mar-13 13:32pm
Dave Kreskowiak 22-Mar-13 13:53pm
Then you DON'T do what you're trying to do. Google for "VNC" and use a library dedicated to the purpose instead of trying to "roll your own" without knowing what you're doing.
Rixterz123 22-Mar-13 13:54pm
oh, yay, it's in C#, which if of course what i'm using!
Dave Kreskowiak 22-Mar-13 14:00pm
It doesn't matter which lanugage you're using.
Rate this: bad
Please Sign up or sign in to vote.

Solution 1


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[^].

Rixterz123 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.
Rixterz123 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.
Rate this: bad
Please Sign up or sign in to vote.

Solution 3

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.

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.
Rixterz123 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)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Mobile
Web02 | 2.8.170622.1 | Last Updated 19 Mar 2013
Copyright © CodeProject, 1999-2017
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100