>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Разработка http://forum.mozilla-russia.org/viewforum.php?id=18 >Что врет - это getImageData или это putImageData http://forum.mozilla-russia.org/viewtopic.php?id=56619 |
Van > 09-10-2012 10:40:52 |
В FF почему то циферки не сходятся с теми что записываю в getImageData, когда их повторно извлекаю их того же самого getImageData для проверки. Есть ли этому объяснение? |
Van > 09-10-2012 15:51:16 |
Чтобы не засорять интернет привел здесь только ссылку на сам вопрос. Почему не сходятся цифры с теми что записываю в getImageData, когда их повторно извлекаю их того же самого getImageData для проверки: Выделить код Код:var x = 256, // 255 является максимальным значением y = 1, // Coordinates of image pixel that we will modify cxy = x*y, can = document.createElement('canvas');can.width = x; can.height = y;document.body.appendChild(can); var ctx = can.getContext('2d'), // Get drawing context o=new Image(); //создание нового объекта o.onload=function() { ctx.drawImage(o,0,0); // размещение объекта на холсте var imDat = ctx.getImageData(0, 0, can.width, can.height);//получаем bitmap for(var j =0; j<cxy;j++){ // Set pixel color - начинаем запись своих чисел (заменяем то что было) imDat.data[j] = j; } ctx.putImageData(imDat, 0, 0);//перезапись рисунка с обновленными данными //повторно извлекаем свои же только что записанные данные для проверки var imDat2 = ctx.getImageData(0, 0, can.width, can.height); var eh; for(var j =0; j<cxy;j++){ // свераем старые и новые данные в порядке возрастания чисел eh = imDat.data[j] == imDat2.data[j]; eh = eh?'':' -----> '+eh; // выводим на печать результаты проверки document.write(j+" ... "+imDat.data[j]+" == "+imDat2.data[j]+ " <b>" +eh+"</b><br>"); } }; o.src="1.jpg"; //любой ваш рисунок Вот это я получаю в браузере, 0 ... 0 == 0 Из диапазона чисел от 0 до 255 процентов 30 - брак ? 09-10-2012 16:01:01 |
Van > 09-10-2012 17:57:12 |
Первоначальный рисунок здесь вообще ни при чем. |
Van > 10-10-2012 00:19:30 |
Пробовал и без png, jpg, тестировал только с прямоугольником холста, результа прежний. Вообще то это не баг браузера. Если заполнение канваса идет равномерно, т.е. рядом расположенные пиксели меняют свое значение скажем на единичку, |
Unghost > 20-10-2012 19:58:49 |
Тема перенесена из форума «Firefox» в форум «Разработка». |
svtux > 04-05-2013 23:01:23 |
Я прошу прощения за археологизм, но на тему использования canvas пока мало информации на русском языке, поэтому напишу, что у вас ошибка в коде, вот здесь: Нельзя просто порядковые номера присвоить данным, а вы делаете именно это. Если поймете здесь свою ошибку, то и проблемы вами озвученной не будет в принципе. Резюмирую: |
Van > 05-05-2013 02:09:40 |
svtux ошибка и правда в этом месте, т.к. других мест как бы не так и много, и видимо Вы знаете причину, но я не могу понять почему так нельзя делать, ведь присваиваемые значения могут быть любыми? в т.ч. и упорядочеными по возрастанию/убыванию ? Что интересно, если закоментировать document.write , то можно увидеть измененную картинку с новыми значениями (от 0 до 255), визуально это серо-белые градиентные полоски расположенные вертикально. И это доказывает что браузер все же воспринял новые значения и отобразил их, а вот почему при повторном считывании обновленных данных проявляется ошибка. Может как то передача по ссылке происходит, а не по значению? |
Van > 05-05-2013 12:51:37 |
okkamas_knife - вот так всегда, Вам понятно мне пока не очень канвас изначально не предназначен для хранения информации - хорошо, не предназначен, но ведь и не запрещено как бы воспользоваться таким положением. var imDat2 - это вторая, объявленная переменная, совершенно новый объект. Выделить код Код:<!DOCTYPE html><HTML><body><script> var x=256,y=100,cxy=x*y*4,can=document.createElement('canvas');can.width=x;can.height=y;document.body.appendChild(can); var ctx=can.getContext('2d'),o=new Image(); o.onload=function(){ ctx.drawImage(o,0,0); var imDat=ctx.getImageData(0,0,can.width,can.height),errr='',i=0; for(var j =0; j<cxy;j++){ //for(var j =0; j<100;j++){ imDat.data[j] = i*1; //imDat.data[j] = 120; //i=i<255?i+1:0; i=i<255?i+1:0; } ctx.putImageData(imDat, 0, 0); i = 0; var imDat2 = ctx.getImageData(0, 0, can.width, can.height),eh,k=0,braks=[]; for(var j=0;j<cxy;j++){eh=imDat.data[j] == imDat2.data[j]; if(eh)eh ='';else{k++;eh = ' -----> '+eh;if(!in_ar(i,braks))braks.push(i);} errr +=j+" ... "+imDat.data[j]+" == "+imDat2.data[j]+ " <b>" +eh+"</b><br>"; i=i<255?i+1:0; } alert("From "+cxy+" -->brak ="+k+"\n\n"+Math.floor((k/cxy)*100)+' % BRAK ?'); /* document.write(errr); document.write("<br><br><h1>FF like it:</h1><br>"); braks.sort(function(a,b){return a-b;}); for(var j in braks)document.write(braks[j]+" "); document.write("<br><h1>From 255 -> "+braks.length+" integers brak, "+ Math.floor((braks.length/255)*100) +"%</h1><br>"); */ }; function in_ar(a,b){for(var c in b)if(b[c]==a)return true} o.src="1.jpg";//любой ваш рисунок ( 256 х 256 например ) </script></body></html>
можно ли пример? наглядно меняющий ситуацию 05-05-2013 13:02:27
оно тем более должно совпадать 05-05-2013 13:05:08
- ПОЧЕМУ ? 05-05-2013 13:08:13 Или все же браузер ? |
Van > 05-05-2013 19:11:38 |
Придумал же кто то примечания, попробую ими воспользоваться: // 255 является максимальным значением Задача поставленная: заменить в рисунке на холсте значения цвета r,g,b,a, включая и альфа канал. Объяснение с wav файлом примерно понятно, в общих чертах, но не очень применительно к рисунку. 05-05-2013 19:24:03 |
svtux > 07-05-2013 04:02:17 |
Прошу прощения, что не сразу понял суть вашего эксперимента. Итак, по-порядку: Van пишет
Не совсем так. Те значения, которые вы присваеваете могут быть любыми, но они должны соответствовать принятому стандарту, и если вы будете присваивать им просто порядковые номера, то, хотя и смысла в этом не вижу, но все же записать так можно. Ваша ошибка в том, что вы используете альфа-канал, не сразу понял описание, но вообще работать должно вот так (ссылка на оригинал): whatwg.org пишет
В частности, нас интересуте то, что я выделил жирным, там написано, что пикселы должны быть возвращены без предварительного умножения на значение альфа-канала, а плотность пикселей возвращенного объекта должна быть 1 (имеется ввиду прозрачность). >Может как то передача по ссылке происходит, а не по значению? Никаких ссылок здесь нет. Все согласно указанным значениям. Как пример, пожалуйста, вот код: Выделить код Код:var x = 256; var y = 1; var cxy = x * y; var can = document.createElement('canvas'); can.width = x; can.height = y; document.body.appendChild(can); var ctx = can.getContext('2d'); // Get drawing context var imDat = ctx.createImageData(x, y); //создаем bitmap for (var j = 0; j < cxy; j++) { // Set pixel color - начинаем запись своих чисел (заменяем то что было) for (var i = 0; i < 4; i++) { imDat.data[4 * j + i] = j; } } ctx.putImageData(imDat, 0, 0); // запись рисунка // повторно извлекаем свои же только что записанные данные для проверки var imDat2 = ctx.getImageData(0, 0, x, y); var eh; var outputString = ""; // здесь будет храниться результат проверки for (var j = 0; j < 4 * cxy; j++) { // свераем старые и новые данные в порядке возрастания чисел eh = imDat.data[j] == imDat2.data[j]; eh = eh ? '' : ' -----> ' + eh; // сохраняем результаты проверки outputString += ( j + " ... " + imDat.data[j] + " == " + imDat2.data[j] + " <b>" + eh + "</b><br>"); } // выводим на печать результаты проверки var newElem = document.createElement('div'); newElem.style.margin = "20px"; newElem.innerHTML = outputString; document.body.appendChild(newElem); То есть если вы прозрачность установите везде в значение 255, например, так: Выделить код Код:for (var j = 0; j < cxy; j++) { // Set pixel color - начинаем запись своих чисел (заменяем то что было) for (var i = 0; i < 3; i++) { imDat.data[4 * j + i] = j; } imDat.data[4 * j + 3] = 255; } то все получится как нужно. okkamas_knife пишет
Очень даже предназначен, и это используется экзотическим способом для сжатия кода: доказательство по ссылке. |
svtux > 07-05-2013 13:36:41 |
Если бы люди всегда делали только то, что нужно вам, или мне, или кому-то еще, а не им самим, то мир, наверное, был бы "серым" и унылым, зато аккуратным и стройным как муравейник или пчелиный улей. То есть я хочу сказать, что подобное явление слишком распространено в человеческом обществе, чтобы заострять внимание на каком-то одном конкретном его проявлении. Кто знает, может быть именно оно является причиной эволюции, её движущей силой. Простой пример: зачем люди запекают яблоки, ведь они и свежие вкусные, причем, как говорят ученые, еще и гораздо более полезные?! |
Van > 07-05-2013 18:19:43 |
svtux спасибо ! Ссылки очень даже нужно изучить (сначала перевести придется конечно). Велосипед точно изобретаю Вы совершенно правы! и к тому весьма экзотическим способом, и никаких извращений, просто переставляя буковки в скриптах специфическим способом пытаюсь решить новые задачи. Для чего нужно хранить данные именно в канвасе - так с тыщу способов применения можно придумать, а и другие способы хранения данных тоже интересны, ну кроме печенек конечно, их же могут отключать прямо в настройках. Присваивать просто порядковые номера смысла в этом конечно же не много, но если даже так записать можно, то значит и более полезные присваивания можно творить. Это же проба, тест можно сказать. Плотность пикселей возвращенного объекта должна быть 1 (имеется ввиду прозрачность) - получается что модификации канваса не позволят делать наложение рисунков? частичное или полное, а жаль! |
Van > 07-05-2013 20:09:06 |
globalAlpha = значение прозрачности Таки да а если к примеру при некотором событии хочу в верхнем рисунке изменить прозрачность отдельных пикселей или групп произвольных пикселей, не квадратиков, чтобы просвечивалась нижняя картинка с 1.0 на 0.4 ? и затем через время на 0.0 ? менять верхнюю картинку на другую заготовку? При плавном изменении прозрачности заготовок несколько потребуется. |
svtux > 09-05-2013 01:21:17 |
При работе с холстом есть одна особенность - он статичен. То есть если вы хотите сделать анимацию, то вам придется каждый раз перерисовывать весь холст заново. В вашем случае это означает следующее: Van пишет
То вам нужно будет перерисовать оба рисунка: нижнюю картинку и верхнюю с нужной вам прозрачностью хоть полностью, хоть частично. Van пишет
И снова для этого нужно будет нанести на холст оба рисунка, предварительно его очистив, разумеется. Van пишет
Заготовку можете вычислять программно в javascript (можно хранить её в памяти, но чаще "дешевле" пересчитать из определенного состояния). Пример по ссылке: |
Van > 09-05-2013 14:06:37 |
Пример интересен. Надо поэкспериментировать. Верхняя картинка где нужные пиксели полностью прозрачны тоже выход, но Телевидение: смена 24 кадров дает впечатление плавного изменения изображения лица человека с серьезным выражением на улыбку, перерисовывать весь холст заново - или часть, т.е. холстов может быть несколько (естественно в качестве демо страницы, т.к. никто реально такое делать не будет) Разница анимация и телевидение. Превращение изображения лица мужчины в изображение лица женщины, ребенка, взрослого, динамическое изменение контуров, цветов, перемещение объекта по экрану (холсту). Тогда и полный ОК! |
Van > 09-05-2013 14:48:14 |
Пример веселенький |
Van > 09-05-2013 18:49:08 |
Ссылки на гугл - универсально! Там правда всего дофигища )))))) Демки конечно интересно, и раньше, и сейчас, |
svtux > 10-05-2013 16:41:13 |
Как вы справедливо заметили, я не ясно выразился. Перерисовывать весь холст, конечно же, не обязательно. Это оправдано далеко не всегда, то есть только если изменяется большая часть изображения на нём. Можно запросто менять лишь ту часть изображения, которая изменилась, хоть большую область, хоть 1 пиксель. Для каждой задачи можно найти несколько решений. Пример я не писал специальнто для этого обсуждения, просто взял уже готовый из своих экспериментов. Так же можно заметить, что вовсе не обязательно работать с битовой картой изображения, можно использовать и глобальный альфа канал для различных буферных холстов, которые потом сводят в один главный. Инструмент достаточно хорошо проработан, и уже написано довольно таки много различных фреймворков для работы с ним. А если использовать аппаратное ускорение при работе с контекстом webgl, то еще и скорость обработки будет настолько высока, что уже можно писать довольно амбициозные 3D приложения. |
Van > 10-05-2013 18:12:47 |
Вот. Пока я тут придумываю, серьезные люди давно изучили, и порешали, |