在 JSF 中创建并显示缩略图 (byte[])

发布于 2024-08-21 20:16:20 字数 2797 浏览 5 评论 0原文

我正在将图像上传到服务器,当图像上传时,它应该向我显示已上传图像的拇指。缩略图未保存在硬盘上我使用InputStream 和OutputStream。为了上传,我是ustig tomahawk。

我的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[]中,任何人都可以告诉我如何显示我的拇指带有 标签?或者任何其他方式。

谢谢 !

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. For upload 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 calls function 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;
}

Now I have my thumbnail but it is in byte[] can any body tell me how to show my thumb with <h:graphicImage> tag? Or any other way.

Thank you !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

℉絮湮 2024-08-28 20:16:20

每个图像都被视为单独的请求。您不能在单个请求/响应周期中同时处理(JSF 的)HTML 响应和图像。您需要将图像/拇指存储在数据存储中的某个位置,该数据存储的寿命比请求长,例如服务器的本地磁盘文件系统(临时文件夹? webcontent 文件夹?),或数据库(临时表?),或会话中。

首先,替换

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

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

,使其生成为

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

src 应该指向有效的 URL

然后,创建一个映射的 HttpServlet/thumbs/*url-pattern 上并实现 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) {}
}

就是这样。更多 servlet 提示可以在本文中找到。

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.

情定在深秋 2024-08-28 20:16:20

graphicImage 标记在 HTML 响应中生成 img 标记。因此,您需要在 graphicImage 标记的 value 属性中提供图像的 URL,该属性将对应于 src 属性。代码>img标签。

您可以:

  • 将缩略图写入文件系统 上可通过 HTTP 从外部访问的路径中。然后,您可以直接在graphicImagevalue 属性中引用该图像,例如/myapp/thumbnail/12345
  • 编写一个 servlet,根据请求提供图像。 Servlet 可以从内存 (HttpSession)、文件系统或数据库读取图像,也可以每次生成图像。在这种情况下,您需要向 servlet 传递一个参数,例如 /myapp/thumbnail.do?filename=12345

简而言之,您需要存储您的 byte[]某处(会话、文件系统、数据库)的缩略图,以便能够直接或通过 servlet 将其作为常规资源提供服务。

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:

  • Write the thumbnail on the 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.
  • Write a 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.

两人的回忆 2024-08-28 20:16:20

Richfaces 已经为您抽象了这一点。检查 ;- 您只需将 byte[] 写入组件提供的 OutputStream 即可。

Richfaces has abstracted this for you. Check <a4j:mediaOutput> - you just write your byte[] to an OutputStream provided by the component.

夏夜暖风 2024-08-28 20:16:20

谢谢埃温利。我重复使用了您的 createThumbnail util 方法。我添加了这个小增强功能,以便在原始图像的宽度小于规定的 maxDim 宽度时返回原始图像。我这样做是因为我遇到了一种情况,该方法返回的图像比原始图像大,并用黑色像素填充。

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

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

        ...

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;
        }

        ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文