2

I have a function to get image dimensions. I send in the return from createObjectURL.

It works fine in getting the dimensions, but I can't get the values back. I am trying to get both values but the issue seems to be that there is a function within the function. And the outer function doesn't know the values that are set in the inner function. When I hard code a value, as in the "qq" below it is fine. So I can see the issues isnt in the return but in the values.

How do you read the values in this situation?

imgSrc = window.URL.createObjectURL(this.files[0]);

var imgSize = getImgSize(imgSrc);
var newWidth = imgSize.retWidth;
var newHeight = imgSize.retHeight;

alert(newWidth);
alert(newHeight);

function getImgSize(imgSrc) {
  var newImg = new Image();

  newImg.onload = function() {
    var nHeight = newImg.height;
    var nWidth = newImg.width;

    //alert('The image size is ' + width + '*' + height);
  }

  newImg.src = imgSrc; //this must be done AFTER setting onload

  return {
    retWidth: nWidth,
    retHeight: 'qq'
  };
}
c0deNinja
  • 3,956
  • 1
  • 29
  • 45
msith718
  • 41
  • 3
  • 8
  • 1
    your variables `nHeight` and `nWidth` only exist in the scope of the `onload` function, see the answer below. – Alex Moldovan Feb 25 '17 at 20:11
  • You can use `Promise`, see [List file sizes of all images on a page (Chrome Extension)](http://stackoverflow.com/questions/41085017/list-file-sizes-of-all-images-on-a-page-chrome-extension/41085297?s=2|0.1129#41085297), [access blob value outside of canvas.ToBlob() async function](http://stackoverflow.com/questions/42458849/access-blob-value-outside-of-canvas-toblob-async-function/) – guest271314 Feb 25 '17 at 20:23

1 Answers1

3

You can't get them back because the .onload is asynchronous the simplest way to deal with this is to call a function from inside the load handler.

function getImage(){
  var imgSrc = window.URL.createObjectURL(this.files[0]);
  getImgSize(imgSrc,useImgSize);
}

function getImgSize(src,fn){
  var img=new Image();
  img.onload=function(){
    fn({width:img.width,height:img.height});
  }
  img.src=src;
}

function useImgSize(dimensions){
  alert(dimensions.width);
  alert(dimensions.height);
}

Here I use a function for each step of the process. You have getImage starting the process. Then you call a utility function that takes an image source and a callback function as parameters (you could directly call the useImgSize function, but the callback allows you to use the utility function for multiple things). Finally you do whatever you want to the dimensions in the useImgSize function.

qw3n
  • 6,236
  • 6
  • 33
  • 62
  • so I add a function inside the load handler, nextStep, but what does nextStep do? I would be passing the values to that function but I am still calling getImageSize...not nextStep... which is receiving the values. I'm a little confused... okay, very confused. – msith718 Feb 25 '17 at 23:51
  • I need to run out for a while but will look at this more closely later on. i really appreciate the feedback. – msith718 Feb 26 '17 at 03:05
  • ok. so, a bit embarrassed to admit that I still dont understand. But... I put the code in and it works. I can access the height and width from the useImageSize function. I was hoping to access the values from the main section (in this example, getImg) so I could call the routine to get the size for different reasons and do different things with it. In this case, I guess I need to do any tasks that need the dimension from the useImageSize, and not the main process, is that right? – msith718 Feb 26 '17 at 20:48
  • Yes, maybe it would help to think of useImageSize as the main function and the other two as merely helpers to get there. – qw3n Feb 27 '17 at 19:37
  • ok. this works. It is tough to use the image sizes for something else, though. as the useImageSize is not my main function. For example, I plan to also call a modal and I need the image size for that as well. But Im sure i can work around it. Im on to my next, and I think, final issue. Waiting for the image to fully load before I remove a "loading" message. Id love your input if you have any thoughts. Im REALLY lost on this one. deferred and promise totally confuse me: http://stackoverflow.com/questions/42493647/remove-background-url-but-only-after-an-image-has-fully-loaded – msith718 Feb 27 '17 at 22:10