hooman naghiee
hooman naghiee

Reputation: 103

load image inside JavaScript function

i have function to get image pixels color

function getImage(imgsrc){
    var img = $( "<img>", {
        src: imgsrc
    });
    var imageMap = new Object();
    img.load(function() {
        var canvas = $('<canvas/>')[0].getContext('2d');
        canvas.width = this.width;
        canvas.height = this.height;
        canvas.drawImage(this, 0, 0, this.width, this.height);
        for(var i = 0;i < this.width;i++){
            imageMap[i] = new Object();
            for(var j = 0;j < this.width;j++){
                var pixelData = canvas.getImageData(i, j, 1, 1).data;
                imageMap[i][j] = rgbToHex(pixelData[0],pixelData[1],pixelData[2]);
            }
        }
            console.log(imageMap[40][40]);
    });
    console.log(imageMap[40][40]);
    return imageMap;
}

but it return undefined(it print 2nd console.log first) what's wrong?

thx.

Upvotes: 2

Views: 2565

Answers (3)

user1693593
user1693593

Reputation:

Now that promises starts to get [have] wide support you can do this instead:

// Define a common load function:
function loadImage(url) {
  return new Promise(function(resolve, reject) {
    var img = new Image;
    img.onload = function() { resolve(this) };
    img.onerror = img.onabort = function() { reject("Error loading image") };
    img.src = url;
  })
}

// Usage:
loadImage("https://i.sstatic.net/ynBVu.gif").then(function(image) {

  // Use the `image` here
  document.body.appendChild(image);

})

The promise will take the callback, states etc. internally. IE will get support in next version (there exists polyfill for it).

Upvotes: 3

Nope
Nope

Reputation: 22329

jQuery.load() is asynchronous, meaning the code will continue while it goes of working away.

If you want to process the imagemap, one option could be to pass a callback you execute ones the imagemap is populated, similar to:

function yourCallback(imageMap){
// ...process imageMap;
}

function getImage(imgsrc, yourCallback) {
    var img = $("<img>", {
        src: imgsrc
    });
    var imageMap = new Object();
    img.load(function () {
        var canvas = $('<canvas/>')[0].getContext('2d');
        canvas.width = this.width;
        canvas.height = this.height;
        canvas.drawImage(this, 0, 0, this.width, this.height);

        for (var i = 0; i < this.width; i++) {
            imageMap[i] = new Object();
            for (var j = 0; j < this.width; j++) {
                var pixelData = canvas.getImageData(i, j, 1, 1).data;
                imageMap[i][j] = rgbToHex(pixelData[0], pixelData[1], pixelData[2]);
            }
        }

        yourCallback(imageMap);
    });
}

getImage(imgsrc,yourCallback);

Upvotes: 1

Cerbrus
Cerbrus

Reputation: 72837

Your function is returning undefined because load is asynchronous. getImage is trying to return something before load finished loading.

You'll need to pass a callback to execute when the image has loaded, to getImage:

function getImage(imgsrc, callback){
    var img = $( "<img>", {
        src: imgsrc
    });
    var imageMap = new Object();
    img.load(function() {
        var canvas = $('<canvas/>')[0].getContext('2d');
        canvas.width = this.width;
        canvas.height = this.height;
        canvas.drawImage(this, 0, 0, this.width, this.height);
        for(var i = 0;i < this.width;i++){
            imageMap[i] = new Object();
            for(var j = 0;j < this.width;j++){
                var pixelData = canvas.getImageData(i, j, 1, 1).data;
                imageMap[i][j] = rgbToHex(pixelData[0],pixelData[1],pixelData[2]);
            }
        }
        console.log(imageMap[40][40]);
        callback(imageMap)
    });
}

Then you just call the function like this:

getImage("http://some.src.jpg", function(imageMap){
    // Do stuff with imageMap here;
});

Of course, you can also define the callback elsewhere:

var myCallback = function(imageMap){
    // Do stuff with imageMap here;
};

getImage("http://some.src.jpg", myCallback);

Upvotes: 4

Related Questions