I\'m uploading image to server and when image is uploaded it should show me a thumb of uploaded image. Thumbnail is not saved on hard disc I use InputStream and OutputStream
The graphicImage
tag generates an img
tag in the HTML response. So you need to provide the URL of an image in the value
attribute of the graphicImage
tag, which will correspond to the src
attribute of the img
tag.
You can either:
filesystem
in a path that is accessible form the outside through HTTP. You can then reference the image directly in the value
attribute in the graphicImage
, e.g. /myapp/thumbnail/12345
.servlet
that serves the image when requested. The servlet can either read the image from memory (HttpSession
), the filesystem, or a database, or generate it each time. In this case you need to pass a parameter to the servlet, e.g. /myapp/thumbnail.do?filename=12345
In short, you will need to store your byte[]
thumbnail somewhere (session, filesystem, database), to be able to serve it as regular resource, either directly or through a servlet.
Richfaces has abstracted this for you. Check <a4j:mediaOutput> - you just write your byte[]
to an OutputStream
provided by the component.
The images counts each as a separate request. You cannot process both the HTML response (of JSF) and the image in a single request/response cycle. You need to store the image/thumb somewhere in a datastore which lives longer than a request, e.g. the server's local disk file system (temp folder? webcontent folder?), or a database (temp table?), or in the session.
First, replace
<h:graphicImage value="#{fileUpload.thumb}" ...
by
<h:graphicImage value="thumbs/#{fileUpload.thumbId}" ...
so that it get generated as
<img src="thumbs/123" ...
(the src
should namely point to a valid URL)
Then, create a HttpServlet
which is mapped on an url-pattern
of /thumbs/*
and implement doGet()
roughly like follows:
Long thumbId = Long.valueOf(request.getPathInfo().substring(1)); // 123
byte[] thumb = getItFromDiskOrDatabaseOrSessionByThumbId(thumbId);
String filename = getOriginalFilenameOfUploadedImageOrInventOne();
response.setContentType(getServletContext().getMimeType(filename));
response.setContentLength(thumb.length);
response.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
BufferedInputStream input = null;
BufferedOutputStream output = null;
try {
input = new BufferedInputStream(new ByteArrayInputStream(thumb));
output = new BufferedOutputStream(response.getOutputStream());
byte[] buffer = new byte[8192];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}
That's it. More servlet hints can be found in this article.
Thanks ewernli. I've reused your createThumbnail util method. I added this little enhancement so that the original image is returned if its width is less than the stipulated maxDim width. I did this because I ran into a situation where the method returned an image that was bigger than the original, padded with black pixels.
ImageIcon imageIcon = new ImageIcon(orig);
Image inImage = imageIcon.getImage();
int origWidth = inImage.getWidth(null);
if(origWidth < maxDim) {
return orig;
}
...