0

我正在使用 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())
4

2 回答 2

1

(这里是蓝的作者)

对于 Blue,它现在实际上使用的是 Java 8 中内置的 Nashorn。(在新的 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 类的更多信息,请访问https:/ /docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html)。

于 2017-01-15T20:04:35.937 回答
0

您需要的是传递给 score 函数的回调函数,该函数将在加载图像时触发:

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

});
于 2017-01-11T11:19:03.157 回答