Rhino中的JavaScript解释器 - 函数返回undefined

时间:2017-01-11 11:12:22

标签: javascript rhino csound

我正在使用Blue中的嵌入式Rhino Interpreter(Csound的音乐合成环境)来生成“乐谱”(乐谱)。在蓝色中,您可以通过编写一个函数然后执行

来完成此操作
score = myFunction()

我的函数使用onLoad获取图像并提取像素信息,这些信息将用于生成分数。问题是我的函数没有足够的时间加载图像并在将数据分配给变量之前返回数据。我尝试过使用setTimeout(),但这没有帮助。

我在浏览器中尝试过此操作,确实返回“未定义”。

基本上我需要一种将分配延迟到分数变量的方法。这可能吗?

谢谢

function score(){
    var img = new Image();
    img.src = "http://static.webshopapp.com/shops/023001/files/024718445/256x256x2/major-dog-barbell-mini.jpg";
    img.crossOrigin = "Anonymous";
    var score = "abc";
    img.onload = function(){
        var canvas = document.createElement("canvas");
        canvas.width = img.width;
        canvas.height = img.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);   
        var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
        score = "i1 0 2 440 0.5\n"
        for (var i=0;i<imgData.data.length;i+=4){
            score += "i1 + 0.1 " + (imgData.data[i] + 500).toString() + " 0.5\n"
        }
        return score;
    }
}
score = score();
// TRY THIS IN BROWSER - RETURNS UNDEFINED
//console.log(score())

2 个答案:

答案 0 :(得分:1)

(Blue的作者)

对于Blue,它实际上使用的是Nashorn,它是内置于Java 8中的。(我在新的Blue版本中将对象重命名为JavaScriptObject。)

Nashorn提供了一个JS引擎,但据我所知,它没有提供浏览器所需的所有API。我运行并调试了您的代码,发现一些关于“文档”和“图像”没有被定义的异常。我使用Java对象重写了代码,例如:

function genScore(){

    var url = new java.net.URL("http://static.webshopapp.com/shops/023001/files/024718445/256x256x2/major-dog-barbell-mini.jpg");
    var img = javax.imageio.ImageIO.read(url);


    score = "i1 0 2 440 0.5\n"
    for (var i = 0; i < img.getHeight(); i++) {
        for (var j = 0; j < img.getWidth(); j++) {
            var rgb = img.getRGB(i, j);
            score += "i1 + 0.1 " + (rgb + 500).toString() + " 0.5\n"
        };
    }
    return score;
}
score = genScore();

并且大致有效。 (我认为如果我理解正确,你的代码只使用红色值;这个代码必须使用位掩码进行修改并移位以获得RGB中的R值;有关Java的BufferedImage类的更多信息可在{{3 }})。

答案 1 :(得分:0)

你需要的是一个传递给分数函数的回调函数,它将在加载图像时触发:

// Adding a callback function as parameter
function score(callback){
    var img = new Image();
    img.src = "http://static.webshopapp.com/shops/023001/files/024718445/256x256x2/major-dog-barbell-mini.jpg";
    img.crossOrigin = "Anonymous";
    var score = "abc";

    img.onload = function(){

        var canvas = document.createElement("canvas");

        canvas.width = img.width;
        canvas.height = img.height;

        var ctx = canvas.getContext("2d");
        ctx.drawImage(img, 0, 0);   
        var imgData=ctx.getImageData(0,0,canvas.width,canvas.height);

        score = "i1 0 2 440 0.5\n"
        for (var i=0;i<imgData.data.length;i+=4)
        {
            score += "i1 + 0.1 " + (imgData.data[i] + 500).toString() + " 0.5\n"
        }
        // Now we can run the callback with our score data
        return callback(score);

    }
}

score(function(score){

  console.log(score);
  // Do your stuff with score data...

});