2010-02-18 2 views
5

이미지를 서버에 업로드하고 이미지를 업로드하면 업로드 된 이미지의 엄지 손가락이 표시됩니다. 섬네일이 하드 디스크에 저장되지 않았습니다. InputStream과 OutputStream을 사용합니다. 업로드를 위해 나는 ustig tomahawk이다.JSF에서 썸네일 (byte []) 만들기 및 표시

내 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)과 단일 요청/응답주기의 이미지 일 수 없습니다. 요청보다 오래 사는 데이터 스토어 어딘가에 이미지/썸을 저장해야합니다 (예 : 서버의 로컬 디스크 파일 시스템 (임시 폴더? 웹 콘텐트 폴더) 또는 데이터베이스 (임시 테이블?) 또는 세션.

첫째, 대체

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

에 의해

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

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

,369합니다 ( src은 즉 유효한 URL을 가리켜 야합니다)로 생성 얻을 그래서

그런 다음, 대략 좋아 /thumbs/*url-pattern에 매핑 된 HttpServlet을 만들고 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 태그는 HTML 응답에 img 태그를 생성합니다. 따라서 태그의 src 속성에 해당하는 graphicImage 태그의 value 속성에 이미지의 URL을 제공해야합니다.

다음 중 하나를 수행 할 수 있습니다

  • 는 HTTP를 통해 액세스 할 양식을 외부를하는 경로에 filesystem에 썸네일을 작성합니다. 그런 다음 graphicImage에있는 value 속성에서 직접 이미지를 참조 할 수 있습니다. /myapp/thumbnail/12345.
  • 요청시 이미지를 제공하는 servlet를 작성하십시오. 서블릿은 메모리 (HttpSession), 파일 시스템 또는 데이터베이스에서 이미지를 읽을 수도 있고 매번 생성 할 수도 있습니다. 이 경우 매개 변수를 서블릿에 전달해야합니다 (예 : /myapp/thumbnail.do?filename=12345

즉, 당신은 직접 또는 서블릿을 통해, 일반 자원으로 역할을 할 수 있도록, 어딘가에 (세션, 파일 시스템, 데이터베이스) 당신의 byte[] 썸네일을 저장해야합니다.

1

Richfaces가 이것을 추상화했습니다. <a4j:mediaOutput>을 확인하십시오. byte[]을 구성 요소가 제공하는 OutputStream에 씁니다.

+0

a4j : mediaOutput은 이미지 내용을 URL (base64 형식)로 인코딩하기 때문에 이미지 크기에 대한 제약 조건을 포함합니다. 작은 아이콘에만 적용됩니다. – vim

0

감사합니다. 나는 createThumbnail util 메소드를 재사용했다. 이 너비가 규정 된 maxDim 너비보다 작은 경우 원본 이미지가 반환되도록이 약간의 향상을 추가했습니다. 이 방법은 원래의 것보다 더 큰 이미지가 검은 픽셀로 채워진 상황을 만났기 때문에 제가했습니다.

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

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

     ... 
관련 문제