2010-02-18 46 views
5

Tôi đang tải hình ảnh lên máy chủ và khi hình ảnh được tải lên, nó sẽ hiển thị cho tôi hình ảnh tải lên. Hình thu nhỏ không được lưu trên đĩa cứng tôi sử dụng InputStream và OutputStream. Để tải lên tôi là ustig tomahawk.Tạo và hiển thị hình thu nhỏ (byte []) trong JSF

index.jsp tôi:

<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 gọi hàm 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; 
} 

Bây giờ tôi có thumbnail của tôi nhưng nó là trong byte[] có thể bất kỳ cơ thể cho tôi biết làm thế nào để hiển thị ngón tay cái của tôi với <h:graphicImage> thẻ? Hoặc bất kỳ cách nào khác.

Cảm ơn bạn!

Trả lời

9

Các hình ảnh tính mỗi số là yêu cầu riêng. Bạn không thể quá trình cả hai phản hồi HTML (của JSF) và hình ảnh trong một chu kỳ yêu cầu/phản hồi. Bạn cần lưu trữ hình ảnh/ngón tay cái ở đâu đó trong kho dữ liệu tồn tại lâu hơn yêu cầu, ví dụ: hệ thống tệp đĩa cục bộ của máy chủ (thư mục temp? thư mục webcontent?) hoặc cơ sở dữ liệu (bảng tạm thời?) hoặc trong phiên.

Thứ nhất, thay thế

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

bởi

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

để nó được tạo ra như

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

(các src cụ thể là phải trỏ đến một URL hợp lệ)

Sau đó, tạo một HttpServlet được ánh xạ vào một url-pattern của /thumbs/* và thực hiện doGet() khoảng thích sau:

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) {} 
} 

Vậy là xong. Các gợi ý về servlet khác có thể được tìm thấy trong this article.

3

Thẻ graphicImage tạo thẻ img trong phản hồi HTML. Vì vậy, bạn cần phải cung cấp URL của hình ảnh trong thuộc tính value của thẻ graphicImage, sẽ tương ứng với thuộc tính src của thẻ img.

Bạn có thể:

  • Viết thumbnail trên filesystem trong một con đường đó là hình thức tiếp cận bên ngoài thông qua HTTP. Sau đó, bạn có thể tham chiếu hình ảnh trực tiếp trong thuộc tính value trong graphicImage, ví dụ: /myapp/thumbnail/12345.
  • Viết servlet phục vụ hình ảnh khi được yêu cầu. Servlet có thể đọc hình ảnh từ bộ nhớ (HttpSession), hệ thống tệp hoặc cơ sở dữ liệu hoặc tạo mỗi lần. Trong trường hợp này, bạn cần chuyển một tham số tới servlet, ví dụ: /myapp/thumbnail.do?filename=12345

Nói tóm lại, bạn sẽ cần phải lưu trữ byte[] thumbnail của bạn ở đâu đó (phiên, hệ thống tập tin, cơ sở dữ liệu), để có thể phục vụ nó như là nguồn tài nguyên thường xuyên, trực tiếp hoặc thông qua một servlet.

1

Richfaces đã trừu tượng hóa điều này cho bạn. Kiểm tra <a4j:mediaOutput> - bạn chỉ cần viết byte[] của mình vào một số OutputStream do thành phần cung cấp.

+0

a4j: mediaOutput chứa ràng buộc về kích thước hình ảnh vì nó mã hóa nội dung hình ảnh thành URL (dạng base64). Nó chỉ áp dụng cho các biểu tượng nhỏ – vim

0

Cảm ơn ewernli. Tôi đã sử dụng lại phương thức createThumbnail util của bạn. Tôi đã thêm phần tăng cường nhỏ này để hình ảnh gốc được trả về nếu chiều rộng của nó nhỏ hơn chiều rộng tối đa quy định. Tôi đã làm điều này bởi vì tôi chạy vào một tình huống mà phương pháp trả lại một hình ảnh lớn hơn bản gốc, được đệm bằng các pixel đen.

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

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

     ... 
Các vấn đề liên quan