0

I need to modify existing code with new requirement: Image dimensions has to be validated before upload from browser. If height or width of image is less than 500 px it has to be increased to 500px.
Here is the code that currently used in our app to upload images.

var fileInputElem  = document.getElementById('P3_FILE');
var fileIndex      = 0;
var deferredObject = $.Deferred();
var s$=apex.widget.waitPopup;

// builds a js array from long string
function clob2Array(clob, size, array) {
  loopCount = Math.floor(clob.length / size) + 1;
  for (var i = 0; i < loopCount; i++) {
    array.push(clob.slice(size * i, size * (i + 1)));
  }
  return array;
}

// converts binaryArray to base64 string
function binaryArray2base64(int8Array) {
  var data = "";
  var bytes = new Uint8Array(int8Array);
  var length = bytes.byteLength;
  for (var i = 0; i < length; i++) {
    data += String.fromCharCode(bytes[i]);
  }
  return btoa(data);
}

// a recursive function that calls itself to upload multiple files synchronously
function uploadFile(pFileIndex) {
  var fileCount    = 0;
  var file         = fileInputElem.files[pFileIndex];
  var reader       = new FileReader();
  var uploadTarget = apex.item("P3_UPLOAD_TARGET").getValue();
  reader.onload = (function(pFile) {
    return function(e) {
      if (pFile) {
        var base64 = binaryArray2base64(e.target.result);
        var f01Array = [];
        f01Array = clob2Array(base64, 30000, f01Array);      
        apex.server.process(
          'UPLOAD_FILE',
          {
            x01: file.name,
            x02: file.type,
            x03: uploadTarget,
            x04: apex.item("P3_FILE_TYPE").getValue(),
            x05: parent.apex.item('P2_SCREEN_TYPE').getValue(), 
            f01: f01Array
          },
          {
            dataType: 'json',
            success: function(data) {
              if (data.j_retn_status == 'SUCCESS') {
                if (fileIndex === 0) {
                  apex.item('P3_PRIMARY_ID').setValue(data.j_primary_id);
                }
                fileIndex++;
                if (fileIndex < fileInputElem.files.length) {
                  // start uploading the next file
                   var d = fileIndex - 1;
                   uploadFile(fileIndex);
                } else {
                    // all files have been uploaded at this point
                    apex.item('P3_FILES_COUNT').setValue(fileIndex);
                    fileInputElem.value = '';
                    deferredObject.resolve('done');
                }
              } else {
                //alert('Oops! Something went terribly wrong. Please try again or contact your application administrator.' + data.j_retn_status);
                 $('#FILEDISP'+pFileIndex).html($('#FILEDISP'+pFileIndex).text()  + '<p class="fa-window-close" aria-hidden="true"></p>' ) ;
              }
            }
          }
        );
      }
    }
  })(file);
  $('#FILEDISP'+pFileIndex).html($('#FILEDISP'+pFileIndex).text()  + '<p class="fa fa-check" aria-hidden="true"></p>' ) ;
  reader.readAsArrayBuffer(file);    
  return deferredObject.promise(); 
}

How can we modify it to validate image dimensions and increase image width or height before upload please?

Thank you!

Leon
  • 21
  • 1
  • 8

1 Answers1

0

You could probably do something like below, although I'd look into using a library for doing something like this in case there are gotchas for certain situations.

const MIN_WIDTH = 500;
const MIN_HEIGHT = 500;

const imageInputEl = document.getElementById('example-image');

imageInputEl.addEventListener("change", handleFiles, false);

function handleFiles() {
  const fileList = this.files;
  const file = fileList[0];
  if ( /\.(jpe?g|png)$/i.test(file.name) ) {
      var reader = new FileReader();

      reader.addEventListener("load", function () {
        var image = new Image();
        image.src = this.result;
        document.getElementById('input-image').src = this.result;
        image.onload = () => {
          const width = image.naturalWidth;
          const height = image.naturalHeight;
          let canvasWidth = MIN_WIDTH;
          let canvasHeight = MIN_HEIGHT;
          if (width >= MIN_WIDTH) canvasWidth = width;
          if (height >= MIN_HEIGHT) canvasHeight = height;
          const canvas = document.createElement("canvas");
          canvas.width = canvasWidth;
          canvas.height = canvasHeight;
          const ctx = canvas.getContext("2d");
          ctx.drawImage(document.getElementById('input-image'), 0, 0, canvasWidth, canvasHeight);
          const resizedImage = canvas.toDataURL("image/png");
          document.getElementById('resized-image').src = resizedImage;
      };
      });

      reader.readAsDataURL(file);
  } else {
   throw new Error('Not a valid image file.');
  }
}
.container {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
<div class="container">
  <input type="file"id="example-image" accept="image/png, image/jpeg">
  <div>
    Input Image:
  </div>
  <img id="input-image">
  <div>
    Resized Image:
  </div>
  <img id="resized-image">
</div>
ryanm
  • 694
  • 1
  • 5
  • 16
  • Thank you for solution! I think it should work for us. Can you please let me know where in our code shall we use your function? Sorry for asking but we did not work on this code and not familiar with it. – Leon Aug 23 '19 at 13:59