ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange |
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();
}
}
}
});
}
2 | No.2 Revision |
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();
}
}
}
});
}
3 | No.3 Revision |
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)