Send images to a webpage (like a video stream)

8,261 views
Skip to first unread message

msdark

unread,
Jun 1, 2011, 2:55:08 PM6/1/11
to nodejs
(sorry for my english)

Hi i writte a little application using node and thrift[1] in the
server side and C++ with thrift in one client side.

The client (c++) send png data to the server (this inside a loop, i
mean.. a lot of images), the server receive that data.

No i wan't to send this image data to a webpage.. the data change, and
i want to show this changes in the webpage.

The idea is create a simple webpage, with some content when i some div
or other tag show the images (and change when a server receive
another) ...

How can i send this data to the webpage?? simple nodejs or using
something like socket.io (http://socket.io) ??

any example of how to send images?

Thanks a lot!!

PD: the data is holded by a binary buffer, so i can send this buffer
to the webpage o write to the disc.
--
Matías Hernández Arellano
Ingeniero de Software/Proyecto en VisionLabs S.A.
CDA ArchlinuxCL

Nathan Rajlich

unread,
Jun 1, 2011, 3:52:01 PM6/1/11
to nod...@googlegroups.com
Change the "src" of an <img> tag?


--
You received this message because you are subscribed to the Google Groups "nodejs" group.
To post to this group, send email to nod...@googlegroups.com.
To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nodejs?hl=en.


msdark

unread,
Jun 1, 2011, 4:07:52 PM6/1/11
to nodejs
I managed to send the image data to webpage using Socket.io
i send a json object like this
{"data": HERE IS THE BINARY DATA OF THE PNG IMAGE, "width":
320,"height":480}

Now i the webpage i read this data into a buffer, so now i need to
create a "in memory" image from this buffer and draw into a webpage.

Maybe i can draw into canvas or using img tag , but i don't know how
to "create the image" in the client side.

(maybe this is off-topic,.. if so. i'm sorry)

Dean Landolt

unread,
Jun 1, 2011, 4:37:14 PM6/1/11
to nod...@googlegroups.com
On Wed, Jun 1, 2011 at 4:07 PM, msdark <msda...@gmail.com> wrote:
I managed to send the image data to webpage using Socket.io
i send a json object like this
{"data": HERE IS THE BINARY DATA OF THE PNG IMAGE, "width":
320,"height":480}

Now i the webpage i read this data into a buffer, so now i need to
create a "in memory" image from this buffer and draw into a webpage.

Maybe i can draw into canvas or using img tag , but i don't know how
to "create the image" in the client side.

(maybe this is off-topic,.. if so. i'm sorry)


I think this is a bit off topic for this list, yes, but I think what you're looking for is data urls.

Paul Spaulding

unread,
Jun 2, 2011, 9:10:51 AM6/2/11
to nod...@googlegroups.com
If the image isn't changing too often (perhaps a couple times per minute), you could simply signal the client via socket.io when it is time to refresh the image and let the client pull the image from the server.  That would be very simple if your architecture allows for that.

Trygve Lie

unread,
Jun 2, 2011, 9:22:44 AM6/2/11
to nod...@googlegroups.com
Hi

You do mention video in the title so if you want to do video (xx frames
pr second) I would make a node.js app which does stream video and
display it in a html5 video tag and then stay away of using WebSockets
for it.

But; if your goal is to push a image from the server to the client on a
regular basis you can just base64 encode the image on the server and
send the base64 string over a WebSocket to the browser. In the browser
you can simply pass the base64 string to a img tag.


I've recently done the same where I grab a image from the camera on a
mobile device and pipe it trough a node.js WebSocket server to other
clients:
http://www.youtube.com/watch?v=jqXo-AEVhK4

It's fairly simple code. The code for it is here:
https://github.com/trygve-lie/demos-html5-realtime
(see under "Demo II - Instant Camera")

Kind regards
Trygve
@trygve_lie

> --
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.

> To view this discussion on the web visit
> https://groups.google.com/d/msg/nodejs/-/ZUhhWWJlV3hfSFFK.


> To post to this group, send email to nod...@googlegroups.com.
> To unsubscribe from this group, send email to nodejs

> +unsub...@googlegroups.com.

msdark

unread,
Jun 2, 2011, 9:38:20 AM6/2/11
to nodejs
Thanks for your example!!..

The initial idea was:

Capture frames from a webcam .. pass this data to a nodejs server and
display in webpage. But i don't know how can i create the "video
stream" if i push images to nodejs (in the capture side i use a c++
app to do some image processing and then encode as png an push into
nodejs server) ...

mscdex

unread,
Jun 2, 2011, 11:49:34 AM6/2/11
to nodejs
On Jun 2, 9:38 am, msdark <msdark...@gmail.com> wrote:
> The initial idea was:
>
> Capture frames from a webcam .. pass this data to a nodejs server and
> display in webpage. But i don't know how can i create the "video
> stream" if i push images to nodejs (in the capture side i use a c++
> app to do some image processing and then encode as png an push into
> nodejs server) ...

FWIW networked webcams have been doing this for years with jpegs and
multipart/x-mixed-replace streams, which is basically a (more
efficient) never-ending multipart response where each successive part
is a new video frame. Obviously this method isn't very good for
providing fast updates, but it works pretty well on all modern
browsers except IE last I checked.

msdark

unread,
Jun 2, 2011, 12:06:11 PM6/2/11
to nodejs
Finally i can't create a multipart/x-mixed-replace stream like
networked webcams (or i don't know how to do that).. instead i send
images to webpages (png images).. this look like live vide streaming
for my webcam.

With c++ i capture and process images, then encode as png, encode into
base64 and send it to nodejs..
With nodejs i push this data into webpage.

Now i searching some method to compress the data between nodejs server
and webpage. maybe something like zlib working in both side (server
and webpage) .. to minimize the size of data sending to webpage.

I'm search to how can use canvas to show the images. or something like
a video player.

Thanks for your comments.

Matt Patenaude

unread,
Jun 2, 2011, 1:15:22 PM6/2/11
to nod...@googlegroups.com, nodejs
multipart/x-mixed-replace shouldn't be particularly hard with Node, and it really would very likely be a good starting point. You should do some research and see if that angle would work for you.

Also, if this really is a video stream, +1 for JPEG vs. PNG: JPEG has better compression for camera-captured images. I doubt you'll get very good compression of image data with zlib since images are already compressed.

-Matt

Sent from my iPhone

> --
> You received this message because you are subscribed to the Google Groups "nodejs" group.

> To post to this group, send email to nod...@googlegroups.com.

> To unsubscribe from this group, send email to nodejs+un...@googlegroups.com.

mscdex

unread,
Jun 2, 2011, 1:47:33 PM6/2/11
to nodejs
On Jun 2, 12:06 pm, msdark <msdark...@gmail.com> wrote:
> Finally i can't create a multipart/x-mixed-replace stream like
> networked webcams (or i don't know how to do that).. instead i send
> images to webpages (png images).. this look like live vide streaming
> for my webcam.

Here's a simple example: https://gist.github.com/566f782827bbd873abfd

msdark

unread,
Jun 2, 2011, 2:06:58 PM6/2/11
to nodejs
this works very good, but how can i "embed" the "video player" into a
normal webpage.. the idea is show the stream and some other data...

msdark

unread,
Jun 2, 2011, 2:07:45 PM6/2/11
to nodejs
My mistake!!.. i can see now..

Thanks a lot mscdex ...

On 2 jun, 13:47, mscdex <msc...@gmail.com> wrote:

msdark

unread,
Jun 2, 2011, 3:05:51 PM6/2/11
to nodejs
mscdex i try to run your code.. (and works) but how can i integrate
with my code..i mean.. i have a function called receiveImage .. this
function receive image data from a c++ application and at same time
push to the webpage using socket.broadcast(data) (socket is a
socket.io instance). ??

mscdex

unread,
Jun 2, 2011, 5:54:45 PM6/2/11
to nodejs
On Jun 2, 3:05 pm, msdark <msdark...@gmail.com> wrote:
> mscdex i try to run your code.. (and works) but how can i integrate
> with my code..i mean.. i have a function called receiveImage .. this
> function receive image data from a c++ application and at same time
> push to the webpage using socket.broadcast(data) (socket is a
> socket.io instance). ??

It'd be separate from your socket.io server. Therefore you wouldn't
socket.broadcast the image data. Just use the http server from the
example in the gist and pass that to your socket.io server. This way
if it's a request for the video stream, it will be handled by the http
server and all other requests will go to socket.io.

msdark

unread,
Jun 10, 2011, 11:14:33 AM6/10/11
to nodejs
I try a lot of thing to make it work ... i use the example from
@mscdex https://gist.github.com/566f782827bbd873abfd but with this i
have a never ending load cycle in the webpage but never image (neither
error or something in the console of chrome webdeveloper tools) ...

The other approach was simply push images (jpeg) to the clients using
socket.broadcast() (socket.io) .. and in the client .. change the src
attribute of img tag to the new data received .. this approach work, i
see the changes of the images like a video streaming, but if i have 3
or more clients the application works very slow in the new clients...

I out of ideas of how i can improve this (or to check if this is a
good idea) .. so.. if any of you have a comment, idea, guideline or
something i would be very appreciate.

My actual code: https://gist.github.com/1019027

On 2 jun, 17:54, mscdex <msc...@gmail.com> wrote:

axs

unread,
Jun 10, 2011, 4:15:05 PM6/10/11
to nod...@googlegroups.com
Keep the URL of the image the same THE SAME. Just change the actual image contents on the server side.

On the client, use a setInterval() to periodically change the image src, and add a cache-busting date stamp on the end. This will force the browser to search for the 'new' image and display it:

<img id="stream" src="http://constant.image.url">
<script>
setInterval(function(){
    var image = document.getElementById('stream');
    image.src = image.src + '?'  + new Date().getTime();
},1000)
</script>

This gets rid of transferring the base64-encoded image, which comes at a price as you've seen.


Regards,
axs

msdark

unread,
Jun 10, 2011, 4:53:07 PM6/10/11
to nodejs
Thanks for your idea @axs .. but i triet (i guess i do right) and i
can't see images.. here is the actual code: https://gist.github.com/1019027

Thanks for your help

axs

unread,
Jun 10, 2011, 6:03:36 PM6/10/11
to nod...@googlegroups.com
get rid of all the socket.io stuff on server and client. Just serve a static image for every "/videoStream" request. Let's say that your C++ code puts out a snapshot.png file, serve it like this:

app.get('/videoStream',function(req,response){
fs.readFile('/snapshot.png', function (err, data) {
   if (err) throw err;

response.writeHead(200, {
'Content-Type': 'image/png',
'Expires': 'Fri, 01 Jan 1990 00:00:00 GMT',
             'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
             'Pragma': 'no-cache'
});
     response.end(data);
});
});


Adjust the update time on the client to match the intervals between image refreshes on the server.

Regards,
axs

mscdex

unread,
Jun 10, 2011, 6:54:47 PM6/10/11
to nodejs
On Jun 10, 4:15 pm, axs <alexst...@gmail.com> wrote:
> On the client, use a setInterval() to periodically change the image src, and
> add a cache-busting date stamp on the end. This will force the browser to
> search for the 'new' image and display it:

Polling is a bad idea imho.

msdark

unread,
Jun 12, 2011, 6:35:12 PM6/12/11
to nodejs
I think polling i a bad idea. So i use socket.io to push the image
data todo
the webpage but using broadcast i have problems when i have more than
one
client (3 or more)... I. Try the @mscdex idea but i can't make it
work... i mean, i can't see the image (the mjpeg video feed) .. i
don't now if this idea is a good approach or not.. but solve the
problem to stream to a webpage so i can see in any device ..

mscdex

unread,
Jun 13, 2011, 2:32:59 AM6/13/11
to nodejs
On Jun 12, 6:35 pm, msdark <msdark...@gmail.com> wrote:
> client (3 or more)... I. Try the @mscdex idea but i can't make it
> work... i mean, i can't see the image (the mjpeg video feed) .. i
> don't now if this idea is a good approach or not.. but solve the
> problem to stream to a webpage so i can see in any device ..

The method I outlined works fine for me on chrome/chromium and opera
11.50. I haven't tested other browsers, but as stated previously it
won't work on IE because IE doesn not support the x-mixed-replace
subtype.

msdark

unread,
Jun 13, 2011, 1:57:25 PM6/13/11
to nodejs
I weird.. i can't see any image with your idea @mcdex in any
browser ...
Maybe is because i receive the jpeg image data encode in base64 and
this is the data that i send to the server when /videoStream is
requested ...

i don't read images from filesystem with node, i receive the data
(jpeg base64) of a jpeg image 320x240, then i need to show this in the
webpage but nothing happend....

On 13 jun, 02:32, mscdex <msc...@gmail.com> wrote:

mscdex

unread,
Jun 13, 2011, 2:36:34 PM6/13/11
to nodejs
On Jun 13, 1:57 pm, msdark <msdark...@gmail.com> wrote:
> I weird.. i can't see any image with your idea  @mcdex in any
> browser ...
> Maybe is because i receive the jpeg image data encode in base64 and
> this is the data that i send to the server when /videoStream is
> requested ...

You shouldn't be sending base64 encoded data to the browser if you
want to use the solution I provided.

> i don't read images from filesystem with node, i receive the data
> (jpeg base64) of a jpeg image 320x240, then i need to show this in the
> webpage but nothing happend....

So the frames you're receiving from your C++ application are already
base64 encoded?

msdark

unread,
Jun 13, 2011, 2:49:18 PM6/13/11
to nodejs
So there is the problem..

I send base64 string data from C++ application (using thrift) to
nodejs ....

The thrift method require that the data will be storage in a string so
i can send this data in base64 or like a binary data (like a unsigned
char* ) ..

I generate a image using a own library, then encode into JPEG and then
into base64 .. send to nodejs (i test if the image is good in nodejs
side, writing this to filesystem) .. then i send this data to
browser ... using socket.io the image data is pushed and showed but is
slow..

So.. i need to send the image data from C++ to nodejs in other
format??? and then use the method of multipart/x-mixed-replace to
show??

On 13 jun, 14:36, mscdex <msc...@gmail.com> wrote:

msdark

unread,
Jun 14, 2011, 10:11:02 AM6/14/11
to nodejs
So.. if i shouldn't send base64 data to the browser, how can i send
the image data??? binary???

msdark

unread,
Jun 14, 2011, 10:28:27 AM6/14/11
to nodejs
I change my code to send (from C++ side) only binary data to nodejs ..
i test if i receive the correct data using.

fs.writeFileSync("image.jpeg",image.data.toString('binary'),'binary');
and the test was successful, so i get the correct image data.

So i try to send this data to the browser with this:

app.get('/videoStream',function(req,response){
response.writeHead(200, {
'Content-Type': 'multipart/x-mixed-replace;boundary="' +
boundary + '"',
'Connection': 'keep-alive',
'Expires': 'Fri, 01 Jan 1990 00:00:00 GMT',
'Cache-Control': 'no-cache, no-store, max-age=0, must-
revalidate',
'Pragma': 'no-cache'
});
response.write("--" + boundary + "\n");
events.addListener('imagen_recibida',function(imagen){
response.write("Content-Type: image/jpeg\n Content-Length:
" +imagen.data.length + "\n\n");
response.write(imagen.data.toString('binary'));
response.write("\n--" + boundary + "\n");
});
});

//this is the function used to receive the data from de C++ side
var receiveImage = function(image,success){
events.emit('imagen_recibida',image);
success(true);
}

And in the browser i check what i receive and i see in wedeveloper
tools of chrome that the mime-type is correct: image/jpeg i see the
size of the data but i see "Pending" in the Status, so it's load
forever and i can't see image.

Maybe the problem is uses the listener to write the data when
arrives ...

Please if you get and idea how can i solve this.....
On 13 jun, 14:49, msdark <msdark...@gmail.com> wrote:

axs

unread,
Jun 14, 2011, 3:44:34 PM6/14/11
to nod...@googlegroups.com
polling is not a bad idea in this case.

the other methods so far have not worked:
1. as mscdex said, multi-part is not supported by all browsers
2. sending base64 data (which is about 1.5x's the data transferred when getting the raw image) is not working smoothly for you and is incurring increased bandwidth

try writing the data to the same image file and refreshing the image on the client side. it may finally get you what you're looking for...

regards,
axs

Reply all
Reply to author
Forward
0 new messages