Legacy way to display binary images is to create a servlet and send the byte content as a stream. This requires a dedicated servlet and probably different servlets dealing with handling cases.
PrimeFaces features a simple but powerful StreamedContent API and p:graphicImage component to display any binary image easily. This binary image could be images stored in a database or images created programmatically on-the-fly. Following are a couple examples for demonstrating how easy it is to display binary images with PrimeFaces.
Images Stored in Database
This example retrieves a blob from a jdbc resultset and provides it’s inputstream as a StreamedContent.
public class BackingBean {
private StreamedContent dbImage;
public BackingBean() {
InputStream dbStream = //Get inputstream of a blob eg javax.sql.Blob.getInputStream() API
dbImage = new DefaultStreamedContent(dbStream, "image/jpeg");
}
//getters and setters
}
<p:graphicImage value="#{backingBean.dbImage}" />

Generated Chart Images
JFreeChart is a popular open source charting library, PrimeFaces also have flash based cool charts but if you want
to use JFreeChart instead you don’t need a wrapper JSF component for this. Just create your chart and define it as
as a streamed content.
public class BackingBean {
private StreamedContent chartImage;
public BackingBean() {
try {
JFreeChart jfreechart = ChartFactory.createPieChart("Turkish Cities", createDataset(), true, true, false);
File chartFile = new File("dynamichart");
ChartUtilities.saveChartAsPNG(chartFile, jfreechart, 375, 300);
chartImage = new DefaultStreamedContent(new FileInputStream(chartFile), "image/png");
} catch (Exception e) {
e.printStackTrace();
}
}
private PieDataset createDataset() {
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("Istanbul", new Double(45.0));
dataset.setValue("Ankara", new Double(15.0));
dataset.setValue("Izmir", new Double(25.2));
dataset.setValue("Antalya", new Double(14.8));
return dataset;
}
//getters and setters
}
<p:graphicImage value="#{backingBean.chartImage}" />
This chart example truly demonstrates the power of PrimeFaces StreamedContent, I’ve created a JSFChartCreator component long time ago which became quite popular in JSF community. The problem was when you wrap a huge API like JFreeChart, flexibility gets lost since it’s just too hard to support every different setting in JFreechart API with a wrapper component. StreamedContent and p:graphicImage simply makes any other JSF component wrapping JFreeChart obselete. Instead with this way you still have the full power of chart api and a very easy way to display it.

Runtime Barcode Creator
Similar to the chart example, an on-the-fly generated barcode can easily be presented. This example uses barbecue project to create barcodes.
public class BackingBean {
private StreamedContent barcode;
public BackingBean() {
try {
File barcodeFile = new File("dynamicbarcode");
BarcodeImageHandler.saveJPEG(BarcodeFactory.createCode128("PRIMEFACES"), barcodeFile);
barcode = new DefaultStreamedContent(new FileInputStream(barcodeFile), "image/jpeg");
} catch (Exception e) {
e.printStackTrace();
}
}
//getters and setters
}
<p:graphicImage value="#{backingBean.barcode}" />

Online Demo
Examples I’ve given here are also available live at PrimeFaces Showcase.
Summary
One of the design principles behind PrimeFaces is to hide complexity and keep the flexibility, this is just one example of it in PrimeFaces.