Создайте и покажите эскиз (байт []) в JSF
Я загружаю изображение на сервер, и когда изображение загружается, оно должно показать мне большой палец загруженного изображения. Миниатюра не сохраняется на жестком диске. Я использую InputStream и OutputStream. Для загрузки i'm ustig tomahawk.
my index.jsp:
<h:form id="uploadForm" enctype="multipart/form-data">
<t:inputFileUpload id="fileupload"
accept="image/*"
storage="file"
value="#{fileUpload.uploadedFile}"
styleClass="fileUploadInput"
required="true"
validator="epacient.FileUploadValidator"
requiredMessage="Obvezna izbira datoteke."
/>
<br />
<h:message for="fileupload" infoStyle="color: green;"
errorStyle="color: red;" />
<br />
<h:commandButton value="Upload" id="fileUploadButton"
action="#{fileUpload.upload}" />
<h:message for="uploadForm" style="color: red;" />
<h:graphicImage value="#{fileUpload.thumb}"
rendered="#{fileUpload.uploaded}" />
</h:form>
fileUpload.upload вызывает функцию String preview()
private String thumb ;
public String preview() throws IOException{
HttpServletResponse response = (HttpServletResponse)FacesContext
.getCurrentInstance().getExternalContext().getResponse();
try {
FacesContext context = FacesContext.getCurrentInstance();
Map requestMap = context.getExternalContext().getApplicationMap();
byte[] bytes = (byte[])(requestMap.get("fileupload_bytes"));
// returns byte[]
byte[] testByte = createThumbnail(bytes, 200);
// here thumbnail is created
} catch (Exception ex) {
ex.printStackTrace();
}
}
createThumbnail:
public static byte[] createThumbnail( byte[] orig, int maxDim) {
try {
ImageIcon imageIcon = new ImageIcon(orig);
Image inImage = imageIcon.getImage();
double scale = (double) maxDim / (double) inImage.getWidth(null);
int scaledW = (int) (scale * inImage.getWidth(null));
int scaledH = (int) (scale * inImage.getHeight(null));
BufferedImage outImage = new BufferedImage(scaledW, scaledH, BufferedImage.TYPE_INT_RGB);
AffineTransform tx = new AffineTransform();
if (scale < 1.0d) {
tx.scale(scale, scale);
}
Graphics2D g2d = outImage.createGraphics();
g2d.drawImage(inImage, tx, null);
g2d.dispose();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(outImage, "JPG", baos);
byte[] bytesOut = baos.toByteArray();
return bytesOut;
} catch (IOException e) {
System.out.println("Erro: " + e.getMessage());
e.printStackTrace();
}
return null;
}
Теперь у меня есть миниатюра, но в byte[]
может ли кто-нибудь сказать мне, как показать мой палец с тегом <h:graphicImage>
? Или любым другим способом.
Спасибо!
Ответы
Ответ 1
Изображения считаются как отдельный запрос. Вы не можете обрабатывать как ответ HTML (JSF), так и изображение в одном цикле запросов/ответов. Вам нужно сохранить изображение/большой палец где-то в хранилище данных, которое живет дольше, чем запрос, например. локальную файловую систему сервера (временную папку? webcontent folder?) или базу данных (временную таблицу?) или в сеансе.
Сначала замените
<h:graphicImage value="#{fileUpload.thumb}" ...
по
<h:graphicImage value="thumbs/#{fileUpload.thumbId}" ...
чтобы он генерировался как
<img src="thumbs/123" ...
(src
должен указывать на действительный URL)
Затем создайте HttpServlet
, который отображается на url-pattern
из /thumbs/*
и реализует doGet()
примерно следующим образом:
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) {}
}
Что это. Дополнительные советы сервлетов можно найти в в этой статье.
Ответ 2
Тег graphicImage
генерирует тег img
в ответе HTML. Поэтому вам нужно указать URL-адрес изображения в атрибуте value
тега graphicImage
, который будет соответствовать атрибуту src
тега img
.
Вы можете:
- Пишите эскиз на
filesystem
в пути, который доступен через внешний вид через HTTP. Затем вы можете ссылаться на изображение непосредственно в атрибуте value
в graphicImage
, например. /myapp/thumbnail/12345
.
- Напишите
servlet
, который будет использовать изображение по запросу. Сервлет может либо считывать изображение из памяти (HttpSession
), либо файловую систему, либо базу данных, либо генерировать ее каждый раз. В этом случае вам необходимо передать параметр сервлету, например. /myapp/thumbnail.do?filename=12345
Короче говоря, вам нужно будет сохранить миниатюру byte[]
где-нибудь (сеанс, файловая система, база данных), чтобы иметь возможность обслуживать ее как обычный ресурс либо напрямую, либо через сервлет.
Ответ 3
Richfaces абстрагировал это для вас. Проверьте <a4j:mediaOutput>
- вы просто пишете byte[]
в OutputStream
, предоставляемом компонентом.
Ответ 4
Спасибо, эверли. Я повторно использовал метод useThumbnail. Я добавил это небольшое улучшение, чтобы исходное изображение было возвращено, если его ширина меньше заданной ширины maxDim. Я сделал это, потому что столкнулся с ситуацией, когда метод возвратил изображение, которое было больше оригинала, дополненное черными пикселями.
ImageIcon imageIcon = new ImageIcon(orig);
Image inImage = imageIcon.getImage();
int origWidth = inImage.getWidth(null);
if(origWidth < maxDim) {
return orig;
}
...