[SPRING]섬네일 이미지 생성과 화면 처리 -(4)

20331 단어 MultipartMultipart

이미지가 정상적으로 업로드 처리가 되었지만, 원본 이미지가 그대로 나오면 데이터를 많이 소비하기 때문에 가능하면 섬네일을 만들어서 만들어서 전송해주고 원본을 보려고 할 때 원본 파일을 보여주는 방식이 더 좋습니다.(특히 목록 페이지는 이미지가 많아지므로 주의해야 합니다.)

섬네일 이미지 처리 과정

  • 업로드된 파일을 저장하고 섬네일 라이브러리를 활용하여 섬네일 파일을 만들어 줍니다.
  • 섬네일 파일은 파일의 맨 앞에 's_'를 붙여서 일반 파일과 구분해줍니다.
  • UploadResultDTO에 getThumbnailURL()을 추가하여 섬네일의 경로를 <img>태그로 처리해줍니다.

섬네일 처리 라이브러리

  • 섬네일을 처리하기 위해서는 java.imageio 패키지를 이용할 수도 있지만 프로젝트에서는 Thumbnailator 라이브러리를 이용합니다.
  • Thumbnailator는 적은 양의 코드만을 이용하여 섬네일을 제작할 수 있고, 가로와 세로 사이즈를 결정하면 비율에 맞게 조정해주는 편리한 기능이 제공됩니다.

Thumbnailator 라이브러리 : https://github.com/coobird/thumbnailator

  • build.gradle 파일에 Thumbnailator을 추가해줍니다.
implementation group: 'net.coobird', name: 'thumbnailator', version: '0.4.14'
  • UploadController 에서는 Thumbnailator 을 import 해준 뒤에 try-catch 부분을 수정해줍니다.
@RestController
@Log4j2
public class UploadController {

    @Value("${part4.upload.path}")  //application.properties의 변수
    private String uploadPath;


    @PostMapping("/uploadAjax")
    public ResponseEntity<List<UploadResultDTO>> uploadFile(MultipartFile[] uploadFiles) {

        List<UploadResultDTO> resultDTOList = new ArrayList<>();

        for (MultipartFile uploadFile : uploadFiles) {

            // 이미지 파일만 업로드 가능
            if(uploadFile.getContentType().startsWith("image") == false){
                // 이미지가 아닌경우 403 Forbidden 반환
                return new ResponseEntity<>(HttpStatus.FORBIDDEN);
            }

            // 실제 파일 이름 IE나 Edge는 전체 경로가 들어오므로
            String originalName = uploadFile.getOriginalFilename();

            String fileName = originalName.substring(originalName.lastIndexOf("\\") + 1);

            log.info("fileName: "+fileName);

            // 날짜 폴더 생성
            String folderPath = makeFolder();

            //UUID
            String uuid = UUID.randomUUID().toString();

            //저장할 파일 이름
            String saveName = uploadPath + File.separator + folderPath + File.separator + uuid +"_"+ fileName;

            Path savePath = Paths.get(saveName);
			<----------------수정할부분--------------->
            try {
                //원본 파일 저장
                uploadFile.transferTo(savePath);
                //섬네일 생성 (섬네일 파일 이름은 중간에 "s_"로 시작하도록)
                String thumbnailSaveName = uploadPath + File.separator + folderPath + File.separator
                        + "s_" + uuid + fileName;
                File thumbnailFile = new File(thumbnailSaveName);

                Thumbnailator.createThumbnail(savePath.toFile(), thumbnailFile,100,100);

                resultDTOList.add(new UploadResultDTO(fileName,uuid,folderPath));
            }catch (IOException e){
                e.printStackTrace();
            </--------------------------------------------/>
            }
        }

  • 코드의 변경은 3라인 정도이고 가로나 세로가 100px 사이즈의 섬네일을 생성하도록 처리합니다.
  • 브라우저에서 파일을 업로드하고 나면 아래 그림처럼 동일한 이미지가 원본 이미지와 섬네일 파일이 생성되는 것을 볼 수 있습니다.
  • 생성된 섬네일은 's_'로 시작하고 파일의 크기가 상대적으로 매우 작은 것을 알 수 있습니다.

브라우저에서 섬네일 처리

  • 생성된 섬네일은 업로드된 파일과 동일한 이름에 's_'가 붙은 형태이므로 구분이 어렵지 않습니다.
  • JSON으로 전달되는 UploadResultDTO에는 getImgURL()처럼 섬네일의 링크를 처리하기 위한 메서드를 추가해줍니다.
  public String getImageURL(){    //추후에 전체 경로가 필요한 경우를 대비하여 생성
        try{
            return URLEncoder.encode(folderPath+"/"+uuid+"_"+fileName,"UTF-8");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return "";
    }
    public String getThumbnailURL(){
        try{
            return URLEncoder.encode(folderPath+"/s_"+uuid+"_"+fileName,"UTF-8");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return "";
    }

여기서 의문점에 대해서 공부해 보았습니다.

  1. 왜 DTO에 메서드를 정의할떄는 getImageURL,getThumbnailURL 로 정의하였는데 접근할때는 단지.imageURL,thumbnailURL 일까?
  2. 왜 굳이 void형이 아니라 String형을 선언해서 리턴값으로 ""을 줬을까?

해결

1.JS에서 getter는 자바에서 알던것과 다소 달랐습니다.
2. 메서드 앞에 get 키워드를 사용하여 정의합니다.(왜get으로 시작했는가)
3. 메서드 이름을 클래스의 프로퍼티처럼 사용할 수 있습니다.
4. 파라미터가 없어야 하며 무언가를 반환해야 합니다.(String타입,리턴을 ""이유)

  • 추가된 getThumbnailURL()은 getImageURL()과 거의 동일하고 중간에 's_'가 추가된 형태 입니다.
  • UploadEx.html에서도 섬네일 이미지가 보이도록 코드를 변경해줍니다.
  // 추가 
     // Ajax 업로드 이후 이미지들을 호출하는 함수 
     function showUploadedImage(arr){

        console.log(arr);

        var divArea = $(".uploadResult");

        for(var i =0; i<arr.length; i++){
            divArea.append("<img src='/display?fileName=" + arr[i].thumbnailURL+"'>");
            //imageURL을 thumbnailURL로 변경
        }
     }
  • 위의 코드를 반영하면 파일 업ㄹ드의 결과가 다음과 같이 섬네일 이미지들만 추가되는것을 볼 수 있습니다.( 업로드된 파일들의 이미지 비율도 자동으로 조정된 결과를 확인할 수 있습니다.)

좋은 웹페이지 즐겨찾기