ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

For the record, here's the way I found to subscribe to a compressed image topic and save the received images to files using rosjava:

@Override
public void onStart(ConnectedNode node) {
  final Log log = node.getLog();
  latch = new CountDownLatch(0);
  Subscriber<CompressedImage> subscriber = node.newSubscriber(topic, "sensor_msgs/CompressedImage");
  log.info("Subscribed to " + topic);

  subscriber.addMessageListener(new MessageListener<CompressedImage>() {
      @Override
      public void onNewMessage(CompressedImage message) {
          log.info("New image is here! Format: " + message.getFormat());

          if (!message.getFormat().contains("jpeg")) {
              log.warn("Only jpeg images are supported");
              return;
          }

          // The latch allows the node to finish saving the image before a new one arrives.
          if (latch.getCount() == 0) {
              latch = new CountDownLatch(1);
              ChannelBuffer buffer = message.getData();
              log.info("Array length: " + buffer.array().length);
              try {
                  // Look for the start of the image inside the buffer
                  // In the tests with TangoRosStreamer, the offset is always 0x3F,
                  // perhaps it's not necessary to search for the index every time.
                  int imageStart = Bytes.indexOf(buffer.array(), JPG_START);
                  if (imageStart < 0) {
                      throw new Exception("Invalid JPG format: start not found");
                  }

                  File outputFile = new File("image_" + Integer.toString(imgNumber) + ".jpg");
                  OutputStream outStream = new FileOutputStream(outputFile);
                  outStream.write(buffer.array(), imageStart, buffer.array().length - imageStart);
                  log.info("Wrote file");
                  outStream.close();
                  imgNumber++;
              } catch (Exception e) {
                  System.out.println("Listener exception: " + e.getClass() + " msg: " + e.getMessage());
              } finally {
                  latch.countDown();
              }
          }
      }
  });
}

For the record, here's the way I found to subscribe to a compressed image topic and save the received images to files using rosjava:rosjava (no Android required):

@Override
public void onStart(ConnectedNode node) {
  final Log log = node.getLog();
  latch = new CountDownLatch(0);
  Subscriber<CompressedImage> subscriber = node.newSubscriber(topic, "sensor_msgs/CompressedImage");
  log.info("Subscribed to " + topic);

  subscriber.addMessageListener(new MessageListener<CompressedImage>() {
      @Override
      public void onNewMessage(CompressedImage message) {
          log.info("New image is here! Format: " + message.getFormat());

          if (!message.getFormat().contains("jpeg")) {
              log.warn("Only jpeg images are supported");
              return;
          }

          // The latch allows the node to finish saving the image before a new one arrives.
          if (latch.getCount() == 0) {
              latch = new CountDownLatch(1);
              ChannelBuffer buffer = message.getData();
              log.info("Array length: " + buffer.array().length);
              try {
                  // Look for the start of the image inside the buffer
                  // In the tests with TangoRosStreamer, the offset is always 0x3F,
                  // perhaps it's not necessary to search for the index every time.
                  int imageStart = Bytes.indexOf(buffer.array(), JPG_START);
                  if (imageStart < 0) {
                      throw new Exception("Invalid JPG format: start not found");
                  }

                  File outputFile = new File("image_" + Integer.toString(imgNumber) + ".jpg");
                  OutputStream outStream = new FileOutputStream(outputFile);
                  outStream.write(buffer.array(), imageStart, buffer.array().length - imageStart);
                  log.info("Wrote file");
                  outStream.close();
                  imgNumber++;
              } catch (Exception e) {
                  System.out.println("Listener exception: " + e.getClass() + " msg: " + e.getMessage());
              } finally {
                  latch.countDown();
              }
          }
      }
  });
}

For the record, here's the way I found to subscribe to a compressed image topic and save the received images to files using rosjava (no Android required):

@Override
public void onStart(ConnectedNode node) {
  final Log log = node.getLog();
  latch = new CountDownLatch(0);
  Subscriber<CompressedImage> subscriber = node.newSubscriber(topic, "sensor_msgs/CompressedImage");
  log.info("Subscribed to " + topic);

  subscriber.addMessageListener(new MessageListener<CompressedImage>() {
      @Override
      public void onNewMessage(CompressedImage message) {
          log.info("New image is here! Format: " + message.getFormat());

          if (!message.getFormat().contains("jpeg")) {
              log.warn("Only jpeg images are supported");
              return;
          }

          // The latch allows the node to finish saving the image before a new one arrives.
          if (latch.getCount() == 0) {
              latch = new CountDownLatch(1);
              ChannelBuffer buffer = message.getData();
              log.info("Array length: " + buffer.array().length);
              try {
                  // Look for the start of the image inside the buffer
                  // In the tests with TangoRosStreamer, the offset is always 0x3F,
                  // perhaps it's not necessary to search for the index every time.
                  int imageStart = Bytes.indexOf(buffer.array(), JPG_START);
                  if (imageStart < 0) {
                      throw new Exception("Invalid JPG format: start not found");
                  }

                  File outputFile = new File("image_" + Integer.toString(imgNumber) + ".jpg");
                  OutputStream outStream = new FileOutputStream(outputFile);
                  outStream.write(buffer.array(), imageStart, buffer.array().length - imageStart);
                  log.info("Wrote file");
                  outStream.close();
                  imgNumber++;
              } catch (Exception e) {
                  System.out.println("Listener exception: " + e.getClass() + " msg: " + e.getMessage());
              } finally {
                  latch.countDown();
              }
          }
      }
  });
}

The byte array can also be converted to a BufferedImage after getting the index of the start (see this answer: http://stackoverflow.com/questions/12705385/how-to-convert-a-byte-to-a-bufferedimage-in-java)