웹 개발

javascript에서 영역 지정한 사각형 영역만큼 java에서 이미지 자르는 방법

노루아부지 2024. 8. 26. 14:54

1. HTML

<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    .area {
      display: flex;
      flex-direction: row;
      flex-wrap: nowrap;
      align-items: stretch;
      justify-content: flex-start;
    }

    .image-area {
      width: 400px;
      min-height: 400px;
      border: 1px solid #ccc;
      flex: 1;
      position: relative;
    }

    .contents-area {
      width: 300px;
      /*height: 400px;*/
      border: 1px solid #ccc;
      flex: 1;
    }

  </style>
  <script type="text/javascript"
          src="${pageContext.request.contextPath}/resources/js/views/common/invisibledetectlog/invisibleDetectLogAddPop.js"></script>
</head>
<body>

<div class="dialogContent">
  <div class="bwfull">
    <div class="userImgContent bw80">
      <div id="drag-and-drop-zone" class="uploader">
        <label class="fileUploadBtn"><span>이미지 업로드</span><input
            type="file" title='Click to add Files'/></label>
      </div>
      <button type="button" class="btn btn-primary" id="btnDetect">검출</button>
    </div>
    <div class="area">
      <div class="image-area" id="image-area"></div>
      <div class="contents-area" id="contents-area"></div>
    </div>
  </div>
</div>
<script>
  const canvas = document.getElementById('image-area');
  let startX, startY;  // 시작점 좌표 저장
  let isDrawing = false;  // 드로잉 상태 플래그
  let clickX = 0;
  let clickY = 0;
  let clickWidth = 0;
  let clickHeight = 0;

  canvas.addEventListener('click', function(event) {
    const rect = canvas.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;

    if (!isDrawing) {
      // 첫 번째 클릭(시작점) 처리
      startX = x;
      startY = y;
      isDrawing = true;
    } else {
      // 두 번째 클릭(끝점) 처리 및 직사각형 그리기
      drawRect(startX, startY, x, y);
      isDrawing = false;  // 드로잉 상태 리셋
    }
  });

  function drawRect(x1, y1, x2, y2) {
    const div = document.createElement('div');
    div.classList.add('drawn-div');

    // 시작점과 끝점의 좌표를 비교하여 직사각형의 위치와 크기 결정
    clickX = Math.min(x1, x2);
    clickY = Math.min(y1, y2);
    clickWidth = Math.abs(x2 - x1);
    clickHeight = Math.abs(y2 - y1);

    // div 스타일 설정
    div.style.left = clickX + 'px';
    div.style.top = clickY + 'px';
    div.style.width = clickWidth + 'px';
    div.style.height = clickHeight + 'px';

    $(".drawn-div").remove();

    // 캔버스에 추가
    canvas.appendChild(div);
  }
</script>
</body>
</html>

 

 

 

2. javascript

let logseq = '';
let displayWidth = 0;
let displayHeight = 0;
let position = [];

$(function() {
  setFileUploader();

  bindEvent();
});

function bindEvent() {
  $("#btnDetect").click(function() {
    let param = {
      logseq: logseq,
      clickX: clickX,
      clickY: clickY,
      clickWidth: clickWidth,
      clickHeight: clickHeight,
      displayWidth: displayWidth,
      displayHeight: displayHeight
    };

    console.table(param);

    // ajax로 clickX, clickY, width, height, logseq 전송
    $.ajax({
      url: CONTEXT_PATH + '/common/invisibledetectlog/detect.json',
      type: 'post',
      data : {"jsonParam" : JSON.stringify(param)},
      // datatype: 'json',
      success: function(data) {
        console.table(data);
        let html = [];
        html.push('<ul>');
        if(data.securityCode === undefined) {
          html.push(getLine('', g_msg('msg.noData')));
          return;
        }

        html.push(getLine(g_msg('grid.securityCode'), data.securityCode));

        if(data.logDt !== undefined) {
          html.push(getLine(g_msg('grid.requestDateTime'), data.logDt));
        }

        if(data.userCode !== undefined) {
          html.push(getLine('사용자 코드', data.userCode));
        }

        if(data.userId !== undefined) {
          html.push(getLine(g_msg('label.userId'), data.userId));
        }

        if(data.userName !== undefined) {
          html.push(getLine(g_msg('label.userName'), data.userName));
        }

        if(data.deptName !== undefined) {
          html.push(getLine(g_msg('label.deptName'), data.deptName));
        }

        if(data.deptPath !== undefined) {
          html.push(getLine(g_msg('grid.userDeptPathName'), data.deptPath));
        }

        if(data.positionName !== undefined) {
          html.push(getLine(g_msg('label.positionName'), data.positionName));
        }

        if(data.clientIp !== undefined) {
          html.push(getLine(g_msg('label.clientIp'), data.clientIp));
        }

        if(data.commName !== undefined) {
          html.push(getLine(g_msg('label.computerName'), data.commName));
        }

        if(data.osVersion !== undefined) {
          html.push(getLine(g_msg('grid.osVersion'), data.osVersion));
        }

        if(data.macList !== undefined) {
          html.push(getLine(g_msg('label.macAddress'), data.macList));
        }
        html.push('</ul>');

        $("#contents-area").html(html.join(''));
      },
      error: function(e) {
        console.log(e);
      }
    });
  });
}

function getLine(label, value) {
  let html = [];
  html.push('<li class="inputGroup">');
  html.push('   <span class="inputListTitle">' + label + '</span>');
  html.push('   <span>' + value + '</span>');
  html.push('</li>');

  return html.join('');
}

function setFileUploader(){
  $("#drag-and-drop-zone").dmUploader({
    url: CONTEXT_PATH + '/common/invisibledetectlog/upload.json',
    auto: true,
    multiple: false,
    queue: false,
    dataType: 'json',
    extFilter : ["png", "jpg", "jpeg"],
    onDragEnter: function(){
      this.addClass('active');
    },
    onDragLeave: function(){
      this.removeClass('active');
    },
    onInit: function(){
      this.find('input[type="text"]').val(g_msg('msg.noSelectFile'));	//선택된 파일이 없습니다.
    },
    onComplete: function(){
    },
    onNewFile: function(id, file){
      uploadID = id;
      // When a new file is added using the file selector or the DnD area

      this.find('input[type="text"]').val(file.name);
    },
    onUploadError: function(id, xhr, status, errorThrown) {},
    onBeforeUpload: function(id){},
    onUploadProgress: function(id, percent){},
    onUploadSuccess: function(id, data){
      console.table(data);
      if('fail' === data.result) {
        alertMessage(data.reason);
      }
      else {
        $("#image-area").html('<img src="' + data.url + '" alt="image" class="img-thumbnail">');
        logseq = data.logseq;

        // image area에 이미지가 로딩되면 이미지 영역의 크기를 구해서 설정
        var img = new Image();
        img.src = data.url;

        img.onload = function() {
          $img = $(".img-thumbnail");
          displayWidth = $img.width();
          displayHeight = $img.height();
        }
      }
    },
    onUploadError: function(id, xhr, status, message){},
    onFallbackMode: function(){},
    onFileSizeError: function(file){},
    onFileTypeError: function(file){},
    onFileExtError: function(file){
      // 파일 타입 틀린 경우
      alertMessage(g_msg("msg.onlyXXFileUpload", "png, jpg, jpeg"));
    }
  });
}

 

 

 

3. java

public DetectDto detect(HttpServletRequest request) throws IOException {
    DetectDto detect = null;
    Map<String, Object> paramMap = requestUtil.getRequestJsonToMap(request, "jsonParam");

    Long logseq = Long.parseLong(paramMap.get("logseq").toString());
    Optional<PcTbInvisibleDetectLog> opt = pcRepository.findById(logseq);
    if (opt.isEmpty()) {
      return new DetectDto();
    }

    PcTbInvisibleDetectLog detectLog = opt.get();
    String filePath = detectLog.getImagePath() + "/" + detectLog.getImageName();
    String ext = filePath.substring(filePath.lastIndexOf(".") + 1);


    BufferedImage image = ImageIO.read(new File(filePath));

    // 원본 width, height
    int originalWidth = image.getWidth();
    int originalHeight = image.getHeight();

    log.info("원본 width : " + originalWidth);
    log.info("원본 height : " + originalHeight);

    // 사용자가 클릭한 영역의 좌표
    int clientLeft = paramMap.get("clickX") == null ? 0 : Integer.parseInt(paramMap.get("clickX").toString());
    int clientTop = paramMap.get("clickY") == null ? 0 : Integer.parseInt(paramMap.get("clickY").toString());
    // 사용자가 클릭한 영역의 width, height
    int clickWidth = paramMap.get("clickWidth") == null ? 0 : Integer.parseInt(paramMap.get("clickWidth").toString());
    int clickHeight = paramMap.get("clickHeight") == null ? 0 : Integer.parseInt(paramMap.get("clickHeight").toString());

    // UI에 표시된 이미지의 width, height
    double displayWidth = paramMap.get("displayWidth") == null ? 0 : Double.parseDouble(paramMap.get("displayWidth").toString());
    double displayHeight = paramMap.get("displayHeight") == null ? 0 : Double.parseDouble(paramMap.get("displayHeight").toString());

    // UI에 표시된 이미지의 width, height를 기준으로 사용자가 클릭한 영역의 좌표를 계산
    int left = (int) ((double) clientLeft / displayWidth * originalWidth);
    int top = (int) ((double) clientTop / displayHeight * originalHeight);

    int width = (int) ((double) clickWidth / displayWidth * originalWidth);
    int height = (int) ((double) clickHeight / displayHeight * originalHeight);

    log.info("x : " + left);
    log.info("y : " + top);
    log.info("w : " + width);
    log.info("h : " + height);

    // 계산된 좌표만큼 이미지 자르기
    BufferedImage cropImage = image.getSubimage(left, top, width, height);
    ImageIO.write(cropImage, "jpg", new File("d:/crop." + ext));

    return detect;
  }

 

728x90
loading