2017-01-11 2 views
0

Я использую встроенный Rhino Interpreter в синем (среда композиции музыки для Csound), чтобы создать «оценку» (нотную запись). В синий цвет вы можете сделать это, написав функцию затем делатьJavaScript в Rhino Interpreter - функция возвращает undefined

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

ответ

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

}); 
+0

Спасибо за ваш ответ, который работает как шарм в браузере, однако он не будет работать в синем, ему нужно что-то вроде формы = myFunction() в основной программе (назначение должно происходить за пределами любые функции). Как вы думаете, я могу это сделать? – DrumPower3004

+0

Характер асинхронных вызовов требует, чтобы вы использовали функции обратного вызова, чтобы вернуть результат. К сожалению, я не знаком с платформой Rhino и Blue, чтобы помочь вам в этом. Вам нужно будет либо поместить счет = myFunction() внутри анонимной функции (где console.log (оценка) находится в коде выше, прямо сейчас), либо подумайте об использовании обещаний, если они доступны. – KostasX

1

(Автор Синих здесь)

Для Blue это фактически использует Nashorn теперь, который встроен в Java 8. (Я переименовал объект в JavaScriptObject в новой версии Blue.)

Nashorn предоставляет JS-движок, но, насколько я понимаю, Nasorn не предоставляет все 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(); 

и что примерно сработало. (Я думаю, что ваш код использует только красные значения, если я правильно понял, этот код нужно было бы модифицировать с помощью битовой маски и сдвинуть, чтобы получить только значение R из RGB; более подробная информация о классе Java BufferedImage доступна по адресу https://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html).

+0

Кроме того, синий код выглядит так, что он только печатает данные об исключении в журнале приложений, что затрудняет его отладку. Я изменил Blue на 2.7.0, чтобы он сообщал о проблемах с кодом, подобных этому пользователю. –

Смежные вопросы