[javascript] 자바 스크립트-파일 업로드; 이미지에 투명한 배경이 있는지 확인

이미지 배경이 투명하지 않으면 이미지 투명도를 확인하고 오류 메시지를 표시하고 싶습니다. 나는이 function hasAlpha(file)그것을 확인하려면 파일이 투명한 배경을 가지고 있지만 내가하지 확인을 통해 그것을 전달하는 방법을 나는 function uploadFile(file)이미 어떤 검사 파일 크기 기능.

if내부 파일 크기 문을 복제하고 if (xhr.upload) {}업로드 된 이미지가 투명한지 확인할 수 있지만 function hasAlpha(file)나머지 코드와 통합하는 방법을 잘 모르겠습니다 .

// File Upload
//
function ekUpload() {
  function Init() {
    console.log("Upload Initialised");

    var fileSelect = document.getElementById("file-upload"),
      fileDrag = document.getElementById("file-drag"),
      submitButton = document.getElementById("submit-button");

    fileSelect.addEventListener("change", fileSelectHandler, false);

    // Is XHR2 available?
    var xhr = new XMLHttpRequest();
    if (xhr.upload) {
      // File Drop
      fileDrag.addEventListener("dragover", fileDragHover, false);
      fileDrag.addEventListener("dragleave", fileDragHover, false);
      fileDrag.addEventListener("drop", fileSelectHandler, false);
    }
  }

  function fileDragHover(e) {
    var fileDrag = document.getElementById("file-drag");

    e.stopPropagation();
    e.preventDefault();

    fileDrag.className =
      e.type === "dragover" ? "hover" : "modal-body file-upload";
  }

  function fileSelectHandler(e) {
    // Fetch FileList object
    var files = e.target.files || e.dataTransfer.files;

    // Cancel event and hover styling
    fileDragHover(e);

    // Process all File objects
    for (var i = 0, f;
      (f = files[i]); i++) {
      parseFile(f);
      uploadFile(f);
    }
  }

  // Output
  function output(msg) {
    // Response
    var m = document.getElementById("messages");
    m.innerHTML = msg;
  }

  function hasAlpha(file) {
    var canvas = file.getElementById("file-image");
    var ctx = canvas.getContext("2d");
    var data = file.getImageData(0, 0, canvas.width, canvas.height).data,
      hasAlphaPixels = false;
    for (var i = 3, n = data.length; i < n; i += 4) {
      if (data[i] < 255) {
        hasAlphaPixels = true;
        break;
      }
    }
    return hasAlphaPixels;
  }

  function parseFile(file) {
    console.log(file.name);
    output("<strong>" + encodeURI(file.name) + "</strong>");

    // var fileType = file.type;
    // console.log(fileType);
    var imageName = file.name;

    var isGood = /\.(?=svg|jpg|png|jpeg)/gi.test(imageName);
    if (isGood) {
      document.getElementById("start").classList.add("hidden");
      document.getElementById("response").classList.remove("hidden");
      document.getElementById("notimage").classList.add("hidden");
      // Thumbnail Preview
      document.getElementById("file-image").classList.remove("hidden");
      document.getElementById("file-image").src = URL.createObjectURL(file);
    } else {
      document.getElementById("file-image").classList.add("hidden");
      document.getElementById("notimage").classList.remove("hidden");
      document.getElementById("start").classList.remove("hidden");
      document.getElementById("response").classList.add("hidden");
      document.getElementById("file-upload-form").reset();
    }
  }

  function uploadFile(file) {
    var xhr = new XMLHttpRequest(),
      fileInput = document.getElementById("class-roster-file"),
      fileSizeLimit = 1024; // In MB

    if (xhr.upload) {
      // Check if file is less than x MB
      if (file.size <= fileSizeLimit * 1024 * 1024) {
        // File received / failed
        xhr.onreadystatechange = function(e) {
          if (xhr.readyState == 4) {
            // Everything is good!
            // document.location.reload(true);
          }
        };

        // Start upload
        xhr.open(
          "POST",
          document.getElementById("file-upload-form").action,
          true
        );
        xhr.setRequestHeader("X-File-Name", file.name);
        xhr.setRequestHeader("X-File-Size", file.size);
        xhr.setRequestHeader("Content-Type", "multipart/form-data");
        xhr.send(file);
      } else {
        output("Please upload a smaller file (< " + fileSizeLimit + " MB).");
      }
    }
  }

  // Check for the various File API support.
  if (window.File && window.FileList && window.FileReader) {
    Init();
  } else {
    document.getElementById("file-drag").style.display = "none";
  }
}
ekUpload();
form {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: left;
  border: 1px solid;
  cursor: pointer;
  height: 90px;
}

img {
  border: 1px solid;
  height: 60px;
  width: 60px;
}

.uploader input[type="file"],
.hidden {
  display: none;
}
<!-- Upload  -->
<form id="file-upload-form" class="uploader">
  <input id="file-upload" type="file" name="fileUpload" accept="image/*" />
  <label for="file-upload" id="file-drag">
    <img id="file-image" src="#" alt="Preview" class="hidden">
    <div id="start">
      <i class="fa fa-download" aria-hidden="true"></i>
      <div>Select a file or drag here</div>
      <div id="notimage" class="hidden">Please select an image</div>
    </div>
    <div id="response" class="hidden">
      <div id="messages"></div>
    </div>
  </label>
</form>
<div class="error hidden">Your logo must have a transparent background. Please set RBGa



답변

귀하의 hasAlpha()기능을 수정 / 수정했습니다 . 이미지로드 이벤트를 해결하거나 이미지 오류 이벤트를 거부하는 약속을 반환합니다. <canvas>이 함수에서 사용하는 숨겨진 요소 도 추가했습니다 . 투명도 검사를 fileSelectHandler()기능에 추가 하고 필요한 경우 다른 곳으로 옮깁니다.

암호:

// File Upload
//
function ekUpload() {
  function Init() {
    console.log("Upload Initialised");

    var fileSelect = document.getElementById("file-upload"),
      fileDrag = document.getElementById("file-drag"),
      submitButton = document.getElementById("submit-button");

    fileSelect.addEventListener("change", fileSelectHandler, false);

    // Is XHR2 available?
    var xhr = new XMLHttpRequest();
    if (xhr.upload) {
      // File Drop
      fileDrag.addEventListener("dragover", fileDragHover, false);
      fileDrag.addEventListener("dragleave", fileDragHover, false);
      fileDrag.addEventListener("drop", fileSelectHandler, false);
    }
  }

  function fileDragHover(e) {
    var fileDrag = document.getElementById("file-drag");

    e.stopPropagation();
    e.preventDefault();

    fileDrag.className =
      e.type === "dragover" ? "hover" : "modal-body file-upload";
  }

  async function fileSelectHandler(e) {
    // Fetch FileList object
    var files = e.target.files || e.dataTransfer.files;

    // Cancel event and hover styling
    fileDragHover(e);

    // Process all File objects
    for (let i = 0; i < files.length; i++) {
      const f = files[i];
      if (await hasAlpha(f)) {
        console.log('Selected image is transparent');
        parseFile(f);
        uploadFile(f);
      }
      else {
        console.log('Selected image is not transparent');
        document.querySelector('#response').classList.remove('hidden');
        document.querySelector('#file-image').classList.add('hidden');
        output('<strong class="warning">Image background is not transparent</strong>');
      }
    }
  }

  // Output
  function output(msg) {
    // Response
    var m = document.getElementById("messages");
    m.innerHTML = msg;
  }

  function hasAlpha(file) {
    return new Promise((resolve, reject) => {
      let hasAlpha = false;
      const canvas = document.querySelector('canvas');
      const ctx = canvas.getContext('2d');

      const img = new Image();
      img.crossOrigin = 'Anonymous';
      img.onerror = reject;
      img.onload = function() {
        canvas.width = img.width;
        canvas.height = img.height;

        ctx.drawImage(img, 0, 0);
        const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;

        for (let j = 0; j < imgData.length; j += 4) {
          if (imgData[j + 3] < 255) {
            hasAlpha = true;
            break;
          }
        }
        resolve(hasAlpha);
      };
      img.src = URL.createObjectURL(file);
    });
  }

  function parseFile(file) {
    console.log(file.name);
    output("<strong>" + encodeURI(file.name) + "</strong>");

    // var fileType = file.type;
    // console.log(fileType);
    var imageName = file.name;

    var isGood = /\.(?=svg|jpg|png|jpeg)/gi.test(imageName);
    if (isGood) {
      document.getElementById("start").classList.add("hidden");
      document.getElementById("response").classList.remove("hidden");
      document.getElementById("notimage").classList.add("hidden");
      // Thumbnail Preview
      document.getElementById("file-image").classList.remove("hidden");
      document.getElementById("file-image").src = URL.createObjectURL(file);
    } else {
      document.getElementById("file-image").classList.add("hidden");
      document.getElementById("notimage").classList.remove("hidden");
      document.getElementById("start").classList.remove("hidden");
      document.getElementById("response").classList.add("hidden");
      document.getElementById("file-upload-form").reset();
    }
  }

  function uploadFile(file) {
    var xhr = new XMLHttpRequest(),
      fileInput = document.getElementById("class-roster-file"),
      fileSizeLimit = 1024; // In MB

    if (xhr.upload) {
      // Check if file is less than x MB
      if (file.size <= fileSizeLimit * 1024 * 1024) {
        // File received / failed
        xhr.onreadystatechange = function(e) {
          if (xhr.readyState == 4) {
            // Everything is good!
            // document.location.reload(true);
          }
        };

        // Start upload
        xhr.open(
          "POST",
          document.getElementById("file-upload-form").action,
          true
        );
        xhr.setRequestHeader("X-File-Name", file.name);
        xhr.setRequestHeader("X-File-Size", file.size);
        xhr.setRequestHeader("Content-Type", "multipart/form-data");
        xhr.send(file);
      } else {
        output("Please upload a smaller file (< " + fileSizeLimit + " MB).");
      }
    }
  }

  // Check for the various File API support.
  if (window.File && window.FileList && window.FileReader) {
    Init();
  } else {
    document.getElementById("file-drag").style.display = "none";
  }
}
ekUpload();
form {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: left;
  border: 1px solid;
  cursor: pointer;
  height: 90px;
}

img {
  border: 1px solid;
  height: 60px;
  width: 60px;
}

.uploader input[type="file"],
.hidden {
  display: none;
}

.warning {
  color: red;
  font-weight: bold;
}
canvas {
  position: absolute;
  top: -2000px;
}
<!-- Upload  -->
<form id="file-upload-form" class="uploader">
  <input id="file-upload" type="file" name="fileUpload" accept="image/*" />
  <label for="file-upload" id="file-drag">
    <img id="file-image" src="#" alt="Preview" class="hidden">
    <div id="start">
      <i class="fa fa-download" aria-hidden="true"></i>
      <div>Select a file or drag here</div>
      <div id="notimage" class="hidden">Please select an image</div>
    </div>
    <div id="response" class="hidden">
      <div id="messages"></div>
    </div>
  </label>
</form>
<div class="error hidden">Your logo must have a transparent background. Please set RBGa</div>
<canvas></canvas>


답변