2014-09-03 2 views
0

Я пытаюсь применить функцию к каждому изображению на странице при ее загрузке. Переменные в моей функции image.onload кажутся глобальными, что приводит к пропуску изображений и неожиданным эффектам (например, изображения, не соответствующие применяемым width).Вызов изображений в цикле создает перекрывающиеся переменные

Вот вся моя JS:

var imgList = document.getElementsByTagName('img'); 
$('img').after('<canvas></canvas>'); 

for (var j = 0; j < imgList.length; j++){ 
    var image = document.getElementsByTagName('img')[j]; 
    var canvas = document.getElementsByTagName('canvas')[j]; 

    image.onload = function(){ 
     console.log(canvas); 
     var ctx = canvas.getContext('2d'); 

     canvas.width = image.width; 
     canvas.height = image.height; 

     ctx.drawImage(image, 0, 0, canvas.width, canvas.height); 
     var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); 
     var pixelNum = imgData.data.length; 

     //initialize brightness for levels 
     var redMax = 0; 
     var redMin = 255; 
     var greenMax = 0; 
     var greenMin = 255; 
     var blueMax = 0; 
     var blueMin = 255; 

     for(var i = 0; i < pixelNum; i += 4){ 
      //set min and max values for each color 
      if (imgData.data[i] > redMax) { redMax = imgData.data[i] }; 
      if (imgData.data[i] < redMin) { redMin = imgData.data[i] }; 
      if (imgData.data[i+1] > greenMax) { greenMax = imgData.data[i+1] }; 
      if (imgData.data[i+1] < greenMin) { greenMin = imgData.data[i+1] }; 
      if (imgData.data[i+2] > blueMax) { blueMax = imgData.data[i+2] }; 
      if (imgData.data[i+2] < blueMin) { blueMin = imgData.data[i+2] }; 
     } 
     console.log(redMin+" "+redMax+" "+blueMin+" "+blueMax+" "+greenMin+" "+greenMax); 

     for(var i = 0; i < pixelNum; i += 4){ 
      //map colors to 0 - 255 range 
      imgData.data[i] = (imgData.data[i] - redMin) * (255/(redMax - redMin)); 
      imgData.data[i+1] = (imgData.data[i+1] - greenMin) * (255/(greenMax - greenMin)); 
      imgData.data[i+2] = (imgData.data[i+2] - blueMin) * (255/(blueMax - blueMin)); 
     } 
     ctx.putImageData(imgData, 0, 0); 

     //remove original img tag 
     $(image).remove(); 
     console.log(image); 

    }; 
}; 

И вот мой вывод консоли (с комментариями ниже):

<canvas> (line 20) 
0 0 0 0 0 0 (line 47) 
<img src="images/cimg1836.jpg"> (line 59) 

<canvas width="400" height="268"> (line 20) 
29 255 18 255 23 255 (line 47) 
<img src="images/cimg1836.jpg"> (line 59) 

-canvas тег добавляется, как и ожидалось. - максимальный максимум и мин не должны быть равны нулю, так как для min установлено значение 255 и максимальное значение 0 (изображение считывается как полностью черные пиксели). - указанное изображение является вторым из двух изображений в разметке.

- первый тег холста выводится на консоль - второе полотно игнорирует стиль img{ width:400px; }, который должен быть унаследован от img. ожидалось. ожидалось.

Как я могу сохранить изображения отличными, то есть держать их в управлении всем кодом и только один раз?

ответ

1

JavaScript не имеет области действия блока, поэтому эти переменные в вашем цикле действительно являются «глобальными».

Я бы переместил все тело цикла в функцию, которая принимает j в качестве аргумента. Таким образом, image и canvas будут уникальны для каждого вызова каждой функции и поэтому не будут «перекрываться» и вызывать эффекты, которые вы видели.

function doMyThing(image_n) { 
    var image = document.getElementsByTagName('img')[image_n]; 
    var canvas = document.getElementsByTagName('canvas')[image_n]; 

    image.onload = function() { /* ... */ }; 
} 

for (var j = 0; j < imgList.length; j++) { 
    doMyThing(j); 
} 

Необходимость таких писак (то есть, вводя функции областей, где вы не обязательно Intuit их) является особенностью JavaScript, и вы должны держать его в задней части вашего ума, как вы продолжите программирование на этом языке.

+0

Спасибо тонну. Я ранее пытался создать функцию и вызывать ее в цикле, но почему-то не получил вызов j в качестве аргумента. Ты спас мне здравый смысл. – AJFarkas

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