<< 2008년 7월 8일 (화) | | 2008년 7월 10일 (목) >>

Java 기반의 이미지 업로드 및 Thumbnail 생성

Java기반의 이미지 리사이징하는 오픈 소스로는 Java Advanced Imaging (JAI), JMagick등이 있으나,  ImageMagick 으로 conver하는 것이 가장 이미지의 원본을 보호하고 콤팩트하게 리사이징되는 것을 확인했습니다.
아래는 사용 방법에 대한 절차를 기술합니다.

1. ImageMagick 소스 다운 로드 및 설치
 - 다운로드 :  http://www.imagemagick.org/script/install-source.php#unix
 - 설치 방법 : ./configure --prefix=/home/k2/server/ImageMagick-6.3.4 --enable-shared;make;make install

2. 이미지 convert 실행 함수 추가
 - 소스는 아래와 같습니다.
private String CONVERT_PROG = "convert";
public boolean convert(String source, String destination,
   int width, int height, int quality)
{
 List<String> command = null;
 try {
  if (quality < 0 || quality > 100)
   quality = 75;
  
  command = new ArrayList<String>(10);
  command.add(CONVERT_PROG);
  command.add("-geometry");
  command.add(width + "x" + height);
  command.add("-quality");
  command.add(Integer.toString(quality));
  command.add(source);
  command.add(destination);   log.info(command);
 } catch (Exception e) {
  log.error(e);
 }
 return exec((String[])command.toArray(new String[1]));
}
private boolean exec(String[] command)
{
 Process proc = null;
 int exitStatus = -1;  try {
  proc = Runtime.getRuntime().exec(command);
 } catch (Exception e) {
  log.error(e);
  return false;
 }  while (true) {
  try {
   exitStatus = proc.waitFor();
   break;
  } catch (java.lang.InterruptedException e) {
   log.debug("Interrupted: Ignoring and waiting");
  }
 }
 if (exitStatus != 0) {
  log.debug("Error executing command: " + exitStatus);
 }
 return (exitStatus == 0);
}

3. Spring에서 이미지 업로드 하기
 - commons-fileupload.jar, commons-io.jar를 활용한 업로드 이미지입니다. 아래는 xxx-servlet.xml에 추가될 내용입니다.

<bean id="multipartResolver"
   class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
   <property name="maxUploadSize" value="1000001"/>
</bean>
 // 해당 Controller에 다음 내용 추가
<property name="multipartResolver" ref="multipartResolver" />
<property name="destinationDir" value="/home/k2/www/test/files" />
 - Controller의 initBinder, onBindAndValidate, onSubmit()함수에 기능 추가
 - initBinder 기능 추가
protected void initBinder(HttpServletRequest request,
  ServletRequestDataBinder binder) throws Exception
{
 log.info("initBinder()");
 binder.registerCustomEditor(String.class, new StringMultipartFileEditor());
 super.initBinder(request, binder);
}
 - onBindAndValidate() 에 Validation기능 추가
protected void onBindAndValidate(HttpServletRequest request,
 Object command, BindException errors) throws Exception
{
 MultipartHttpServletRequest multipartRequest = null;
 MultipartFile  cfile = null;
 log.info("onBindAndValidate()");
 User user = (User) command;
 if (user != null) {
  String file = user.getFile();
  if (file != null) {
   multipartRequest = (MultipartHttpServletRequest) request;
   cfile = multipartRequest.getFile("file");
  }
  if (!errors.hasErrors()) {
   if (cfile != null) {
    if (cfile.getSize() > 1000000)
     errors.rejectValue("file", "error.profile.fileSize");
   }
  }
  if (!errors.hasErrors()) {
   if (cfile != null) {
    String ext = this.getExtensionFile(cfile).toLowerCase();
    if (!"jpg".equals(ext) && !"gif".equals(ext) && !"png".equals(ext))
     errors.rejectValue("file", "error.profile.fileGroup");
   }
  }
 }
 super.onBindAndValidate(request, command, errors);
}
 - onSubmit()에 기능 추가
protected ModelAndView onSubmit(HttpServletRequest request, 
   HttpServletResponse response,
 Object command, BindException errors) throws Exception
{
 log.info("onSubmit()");
 User user = (User) command;
 String srcPath = null;
 String destPath = null;
 if (user != null) {
  String file = user.getFile();
  if (file != null) {
   MultipartHttpServletRequest multipartRequest =
(MultipartHttpServletRequest) request;
   MultipartFile  cfile =  multipartRequest.getFile("file");
   File dirPath = new File(destinationDir);
   if (!dirPath.exists())
    dirPath.mkdirs();
   String sep = System.getProperty("file.separator");
   File uploadedFile = new File(destinationDir + sep + user.getUsername()
+ "_" + cfile.getOriginalFilename());
   FileCopyUtils.copy(cfile.getInputStream(), new FileOutputStream(uploadedFile));
   srcPath = destinationDir + sep + user.getUsername() + "_" +
cfile.getOriginalFilename();
   destPath = destinationDir + sep +
"thumb_" + user.getUsername() + "_" + cfile.getOriginalFilename();
   new CmdUtil().convert(srcPath, destPath, 78, 78, 95);
   //new CmdUtil().exec() 사용해서 rcp기능 추가
   user.setFile(destPath);
  }
  this.daoFacade.updateUser(user);
 }
 return super.onSubmit(request, response, command, errors);
}
 - Setter 추가
public void setMultipartResolver(MultipartResolver multipartResolver) 
{
 this.multipartResolver = multipartResolver;
}
 
public void setDestinationDir(String destinationDir)
{
      this.destinationDir = destinationDir;
}
이상으로 주요 중요한 기능들만 알면 쉽게 이미지 업로드해서 Thumnail 이미지까지 생성하는 방법을 기술했습니다. 도움이 되었으면 하네요. ^^