4

I have image content as byte[] from database.

private byte[] image;

How can I show that byte array as a real graphic image in JSF page?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
user3364181
  • 531
  • 3
  • 14
  • 32

2 Answers2

12

This is not directly possible with <h:graphicImage>. It can only point to an URL, not to a byte[] nor InputStream. Basically, you need to make sure that those bytes are directly available as a HTTP response on the given URL, which you can then use in <h:graphicImage> (or even plain HTML <img>).

Provided that you're identifying the image by its ID like so:

<h:graphicImage value="/image/#{someBean.imageId}" />

Here's a kickoff example of such a servlet:

@WebServlet("/image/*")
public class ImageServlet extends HttpServlet {

    @EJB
    private ImageService service;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Long id = Long.valueOf(request.getPathInfo().substring(1));
        Image image = service.find(id);
        response.setContentType(getServletContext().getMimeType(image.getName()));
        response.setContentLength(image.getBytes().length);
        response.getOutputStream().write(image.getBytes());
    }

}

A more advanced abstract template for a static resource servlet, supporting HTTP caching, can be found in this answer, along with a concrete example for serving from database.

If you happen to use JSF utility library OmniFaces on a JSF 2.2 + CDI environment, then you can instead use its <o:graphicImage> which can be used much more intuitively.

<o:graphicImage value="#{imageBean.getBytes(someBean.imageId)}" />

@Named
@ApplicationScoped
public class ImageBean {

    @EJB
    private ImageService service;

    public byte[] getBytes(Long imageId) {
        return service.getImageBytes(imageId);
    }

}
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • i have only array of bytes from database nothing else, and i am using jsf so i have only managedBean, can you help me with that – user3364181 Jun 03 '15 at 07:35
  • Yes certainly. See above answer for kickoff examples of two possible ways. Just alter them if necessary to fit your situation. – BalusC Jun 03 '15 at 07:36
  • @Balus May I ask what data type or from which package Image is in Image image = service.find(id); Is the Image image on that line a byte[], a Blob or something else? Thanks – heisenberg Nov 30 '16 at 09:32
  • @p3ace: It's just your custom class. See also a.o. http://stackoverflow.com/q/1727603 and http://stackoverflow.com/q/30639785 – BalusC Nov 30 '16 at 09:35
  • @Balus Thank you. Still trying to absorb and understand every piece. – heisenberg Nov 30 '16 at 09:40
  • 2nd link ( ) broken – sandwood Nov 17 '17 at 14:33
5

Just bind one String variable to image on UI.

<img src="data:image/png;base64, "#{imageString}">

For example you are loading the image byte[] from database then first encode it in base 64 String.

String imageString= new String(Base64.encodeBase64(byte array fetched from database));
Abhishek Jha
  • 111
  • 1
  • 3
  • although it might (does) work, page-caching wise this is not the best solution if you want to cache the page but refresh the image. – Kukeltje Dec 05 '18 at 09:13
  • 2
    Hi all, this answer is correct but the img element is supposed to be written like this: – andydoe Dec 21 '21 at 12:09