Создайте и покажите миниатюру (байт []) в JSF

Я загружаю изображение на сервер и когда изображение загружается, это должно показать мне ползунок загруженного изображения. Миниатюра не сохраняется на жестком диске, я использую InputStream и OutputStream. Для загрузки я - ustig томагавк.

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

Спасибо!

5
задан YoYo 16 July 2016 в 23:29
поделиться

4 ответа

Изображения считаются каждый как отдельный запрос. Вы не можете обрабатывать и HTML-ответ (от JSF), и изображение в одном цикле запроса/ответа. Вам нужно хранить изображение/палец где-то в хранилище данных, которое живет дольше, чем запрос, например, в файловой системе локального диска сервера (папка temp? папка webcontent?), или в базе данных (таблица temp?), или в сессии.

Сначала замените

<h:graphicImage value="#{fileUpload.thumb}" ...

на

<h:graphicImage value="thumbs/#{fileUpload.thumbId}" ...

так, чтобы он генерировался как

<img src="thumbs/123" ...

(src должен указывать именно на действительный URL)

Затем, создайте HttpServlet, который отображается на url-шаблон из /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) {}
}

Вот и все. Больше советов по сервлетам можно найти в этой статье.

9
ответ дан 18 December 2019 в 14:45
поделиться

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

Вы можете либо:

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

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

3
ответ дан 18 December 2019 в 14:45
поделиться

Richfaces абстрагировал это для вас. Посмотрите - вы просто записываете свой байт[] в OutputStream, предоставляемый компонентом.

1
ответ дан 18 December 2019 в 14:45
поделиться

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

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

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

        ...
0
ответ дан 18 December 2019 в 14:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: