Ask Your Question

Display ros image on webpage using roslibjs

asked 2014-04-28 19:18:41 -0500

Brijendra Singh gravatar image

updated 2014-04-28 19:24:21 -0500

Hi all,
I am using ros hydro and publishing compressed image on a topic /cameraColor. Also, I am using rosjslib(webpage) to interact with rosbridge_server. Now I want to display image on webpage subscribing to topic mentioned.
Action done by me: I have used python opencv to save image from that topic in a jpeg file (open cv has method to save image in any format)and then trying to open file and encode it into base64 string . Now I am publishing this base64 string in a seperate topic /base64Image. After subscribing this /base64Image I am able to display image on webpage. But this is a workaround and I am not satisfied with solution. Please suggest me some way to display image on webpage by subscribing to some topic without saving image in jpeg format. Some way to convert ros image in a base64 format directly will be better. I am posting my code for both python code at server side and javascript code in webpage.
Also, please suggest some way to display video from ros on webpage using rosjslib.
Any help will be appreciated.

Thank you.
My code: Python code to convert ros image into base64 and publishig
def __init__(self):
self.image_pub = rospy.Publisher("image_topic_2",Image)
self.imagePub = rospy.Publisher("imageJpeg",String)
print "1"
#cv.NamedWindow("Image window", 1)
self.bridge = CvBridge()
self.image_sub = rospy.Subscriber("/usb_cam/image_raw",Image,self.callback)#/camera/rgb/image_color
self.counter = 0
def callback(self,data):
#print "2"
   cv_image = self.bridge.imgmsg_to_cv(data, "bgr8")
 fileName = "foo_"+str(strftime("%H:%M:%S", gmtime()))
 cv.SaveImage("images/"+fileName+".jpg", cv_image)#"+str(strftime("%H:%M:%S", gmtime()))+"
 image_64 = base64.encodestring(open("images/"+fileName+".jpg","rb").read())
except CvBridgeError, e:
 print e

Javascript code on webpage using rosjslib
//Subscribing Images on Capture image click
imageRos.subscribe(function(message) {
 if(imageFlag === true){
// console.log(;
// var encoded = btoa (unescape(encodeURIComponent(;
  var ImageData1="data:image/jpeg;base64,";

// ImageData1 = "data:image/jpeg;base64,"+ ImageData1;
  displayImage = document.getElementById("topImage1img1");
  displayImage.setAttribute('src', ImageData1);
 imageFlag = false;
// console.log("imageclicked:"+ImageData1);



edit retag flag offensive close merge delete



I had the same problem. My solution was:

    var imageTopic = new ROSLIB.Topic({
    ros : ros,
    name : '/camera/image/compressed',
    messageType : 'sensor_msgs/CompressedImage'

subscribe the compressed image. The normal image is pixeldata, so uncompressed.

Swoncen gravatar image Swoncen  ( 2017-01-22 15:46:36 -0500 )edit

3 Answers

Sort by » oldest newest most voted

answered 2014-04-28 20:18:39 -0500

Wolf gravatar image

Why don't you use mjpeg_sever ( ) ?

You can not only use it as full-page requesting e. g.


as mentioned in the tutorial you can also embed the image in your page's img tags llike:

<img src="http://localhost:8080/stream?topic=/IMAGE_TOPIC" />
edit flag offensive delete link more


Thanks a lot man. I was not aware of this package. After installing the package it is working awesome.

Brijendra Singh gravatar image Brijendra Singh  ( 2014-04-29 20:17:17 -0500 )edit

How to stream those video from another computer which is connected to the same private network

robobee gravatar image robobee  ( 2015-06-19 04:32:33 -0500 )edit

answered 2016-12-07 08:50:46 -0500

Saif Alabachi gravatar image

mjpeg_server has been deprecated. And the video_server package doesn't support indigo or lately ros version. If your code above can stream without any flickering. I can tell this is the best way to stream a video from ROS image raw, and I will do the same with my problem. If you figure out any other effecient way can you please share it with me. Thanks.

edit flag offensive delete link more

answered 2019-05-21 16:14:29 -0500

Rein gravatar image

updated 2019-05-21 16:16:41 -0500

You could decode the uint8[] array raw image and encode it as jpeg as follows:

  import jpeg from 'jpeg-js'

  function rgb8ImageToBase64Jpeg (msg) {
    var raw = atob(
    var array = new Uint8Array(new ArrayBuffer(raw.length))
    for (let i = 0; i < raw.length; i++) {
      array[i] = raw.charCodeAt(i)

    var frameData = Buffer.alloc(msg.width * msg.height * 4)
    for (let i = 0; i < msg.width * msg.height; i++) {
      frameData[4 * i + 0] = array[3 * i + 0]
      frameData[4 * i + 1] = array[3 * i + 1]
      frameData[4 * i + 2] = array[3 * i + 2]
      frameData[4 * i + 3] = 0
    var rawImageData = {
      data: frameData,
      width: msg.width,
      height: msg.height
    return jpeg.encode(rawImageData, 50).data.toString('base64')

I do agree it is better to send a compressed image since this reduces the bandwidth. Or use the mentioned mjpeg server that is now named

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2014-04-28 19:18:41 -0500

Seen: 3,401 times

Last updated: May 21 '19