2

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.

1
  • It's 'cause the load is asynchronous. You can't return from an asynchronous call. Commented Feb 9, 2015 at 8:57

3 Answers 3

4

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);
Sign up to request clarification or add additional context in comments.

Comments

3

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).

1 Comment

This is the most accurate answer now, since all current browsers support Promises.
1

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.