2010-02-18 4 views
5

Я загружаю изображение на сервер, и когда изображение загружается, оно должно показать мне большой палец загруженного изображения. Миниатюра не сохраняется на жестком диске. Я использую InputStream и OutputStream. Для загрузки i'm ustig tomahawk.Создайте и покажите миниатюру (байт []) в JSF

мой 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> тегов? Или любым другим способом.

Спасибо!

ответ

9

Сортировка по убыванию Отдельный запрос. Вы не можете процесс как ответ 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) {} 
} 

Вот и все. Больше подсказок сервлетов можно найти в this article.

3

Тег graphicImage генерирует тег img в ответе HTML. Поэтому вам необходимо указать URL-адрес изображения в атрибуте value тега graphicImage, который будет соответствовать атрибуту src тега img.

Вы можете:

  • Написать миниатюру на filesystem в пути, который является доступной форме снаружи через HTTP. Затем вы можете ссылаться на изображение непосредственно в атрибуте value в graphicImage, например. /myapp/thumbnail/12345.
  • Напишите servlet, который служит изображению, когда требуется. Сервлет может либо считывать изображение из памяти (HttpSession), либо в файловую систему, либо в базу данных, либо генерировать ее каждый раз. В этом случае вам необходимо передать параметр сервлету, например. /myapp/thumbnail.do?filename=12345

Короче говоря, вам нужно будет хранить byte[] миниатюру где-то (сеанса, файловой системы, базы данных), чтобы быть в состоянии обслуживать его как обычный ресурс, либо непосредственно, либо через сервлет.

1

Richfaces абстрагировал это для вас. Проверьте <a4j:mediaOutput> - вы просто напишите byte[] на номер OutputStream, предоставляемый компонентом.

+0

a4j: mediaOutput содержит ограничение на размер изображения, поскольку он кодирует содержимое изображения в URL (форма base64). Он применим только для небольших значков – vim

0

Спасибо, ewernli. Я повторно использовал метод useThumbnail. Я добавил это небольшое улучшение, чтобы исходное изображение было возвращено, если его ширина меньше заданной ширины maxDim. Я сделал это, потому что столкнулся с ситуацией, когда метод возвращал изображение, которое было больше оригинала, дополненное черными пикселями.

 ImageIcon imageIcon = new ImageIcon(orig); 
     Image inImage = imageIcon.getImage(); 

     int origWidth = inImage.getWidth(null); 
     if(origWidth < maxDim) { 
      return orig; 
     } 

     ... 
Смежные вопросы