![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Регистрация: Jul 2011
Сообщений: 32
|
Всем - добрый день!
Вопрос уже задавал на другом форуме, однако специализация и представительность этого форума внушают мне столь обширные надежды, что можно и нескромно повториться. Задача - получить адреса пикселей BitmapData до помещения связанного объекта Bitmap в список отображения (для реализации специфической заливки отображаемой фигуры, созданной средствами векторной графики). Однако, единственный способ, который пришел мне в голову, не работает: var tmpSh:Shape = new Shape();
tmpSh.graphics.beginFill(0xFF00FF, 1);
tmpSh.graphics.drawPath(commands, data);
tmpSh.graphics.endFill();
var r:Rectangle = tmpSh.getRect(stage);
var pt:Point = r.topLeft;
var pixelValue:uint, pixelValueMask:uint, i:int = 0, j:int = 0;
var bmpdata:BitmapData = new BitmapData(r.width, r.height, false, 0xFF0000);
bmpdata.draw(tmpSh);
var arr:Vector.<String> = new Vector.<String>();
for (i = 0; i < r.width-1; i++) {
for (j = 0; j < r.height-1; j++) {
pixelValue = bmpdata.getPixel(i, j);
if (arr.length == 0 || arr.indexOf(("0x"+pixelValue.toString(16))) < 0) arr.push("0x"+ pixelValue.toString(16));
}
}
trace(arr);
|
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
var tmpSh:Shape = new Shape(); tmpSh.graphics.beginFill(0xFF00FF, 1); tmpSh.graphics.drawRect(5, 5, 20, 20);// drawPath(commands, data); tmpSh.graphics.endFill(); var pixelValue:uint, pixelValueMask:uint, i:int = 0, j:int = 0; var bmpdata:BitmapData = new BitmapData(tmpSh.width, tmpSh.height, false, 0xFF0000); bmpdata.draw(tmpSh); var arr:Vector.<String> = new Vector.<String>(); for (i = 0; i < tmpSh.width-1; i++) { for (j = 0; j < tmpSh.height-1; j++) { pixelValue = bmpdata.getPixel(i, j); if (arr.length == 0 || arr.indexOf(("0x"+pixelValue.toString(16))) < 0) arr.push("0x"+ pixelValue.toString(16)); } } trace(arr); // 0xff0000,0xff00ff
__________________
Reality.getBounds(this); |
|
|||||
|
Регистрация: Jul 2011
Сообщений: 32
|
Спасибо, за оперативный ответ.
Думаю, Вас бы очень повеселило выражение моего лица, с которым смотрю на Цитата:
P.S. "Внутренняя" функция ни при чем - квадрат возвращает 2 цвета...Что-то возле drawPath... P.P.S. Если определяю параметры commands, data внутри "внутренней" функции, то нахожу 2 цвета в bitmapData, при попытке передать параметры извне - 1 цвет. Добавлено через 1 час 43 минуты Все понял. paintSh(this) в моей реализации передает ссылку на глобальный объект вместо экземпляра класса. Досадный ляп. Большое спасибо, Wolsh. P.S. И это не то . Так не долго в рассудке повредитьсяДобавлено через 3 часа 57 минут Несмотря на то, что, благодаря Wolsh, доступ к адресам пикселей оказался открыт , академический интерес к проблеме остался (пример сугубо условный):package game { import flash.display.Sprite; public class Example extends Sprite { public function Example() { var er:MyClass = new MyClass(); addChild(er); } } } package game { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Shape; import flash.geom.Point; import flash.geom.Rectangle; public class MyClass extends Bitmap { private var commands:Vector.<int>; private var data:Vector.<Number>; public function MyClass() { var thisbitmapdata:BitmapData = new BitmapData(800, 600, true, 0x80FFFFFF); this.bitmapData = thisbitmapdata; commands = Vector.<int>([1, 2, 2, 2, 2]); data = Vector.<Number>([5, 5, 20, 5, 20, 25, 5, 25, 5, 5]); var i:int; var paintBm:Function = function(bmp:Bitmap):void { trace(bmp); var tmpSh:Shape = new Shape(); tmpSh.graphics.beginFill(0xFF00FF, 1); tmpSh.graphics.drawPath(commands, data); //tmpSh.graphics.drawPath(Vector.<int>([1, 2, 2, 2, 2]), Vector.<Number>([5, 5, 20, 5, 20, 25, 5, 25, 5, 5])); tmpSh.graphics.endFill(); var r:Rectangle = tmpSh.getRect(stage); var pixelValue:uint; var arr:Vector.<String> = new Vector.<String>(); var bmpdata:BitmapData = new BitmapData(r.width, r.height, false, 0xFF0000); bmpdata.draw(tmpSh); for (var m:int = 0; m < r.width-1; m++) { for (var j:int = 0; j < r.height-1; j++) { pixelValue = bmpdata.getPixel(m, j); if (arr.length == 0 || arr.indexOf(("0x"+pixelValue.toString(16))) < 0) arr.push("0x"+ pixelValue.toString(16)); } } trace(arr); bmp.bitmapData.draw(tmpSh); } while(i < 660) { for each (var e:Number in data) data[data.indexOf(e)] = e + i; paintBm(this); i += 50; } } } } Добавлено через 7 часов 3 минуты Ну и теперь совсем лишившее меня каких-либо идей обстоятельство: при попытке проследить связи объектов теми средствами, что дает FlashDeveloper (точки останова ставил на <bmpdata.draw(tmpSh);> и <paintBm(this);>), обнаружил изменение в поведении программы - теперь выводятся все пикселы массива..., т.е. пошаговое действие отличается от нормальной работы. Внятного объяснения не имею. Добавлено через 7 часов 38 минут В общем, размещение среди полей класса, а не во внутренней функции, решает проблему. Тему можно закрыть. Последний раз редактировалось Gantenbain; 01.08.2011 в 16:43. |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
В 10 плеере у БитмапДаты появился метод getVector, возвращающий Вектор с ARGB-значениями всех пикселей заданного прямоугольника битмапдаты. Например
...... var tmpSh:Shape = new Shape(); tmpSh.graphics.beginFill(0xFF00FF, 1); tmpSh.graphics.drawRect(5, 5, 20, 20);// drawPath(commands, data); tmpSh.graphics.endFill(); var pixelValue:uint, pixelValueMask:uint, i:int = 0, j:int = 0; var bmpdata:BitmapData = new BitmapData(tmpSh.width, tmpSh.height, false, 0xFF0000); bmpdata.draw(tmpSh); var pixels:Vector.<uint> = bmpdata.getVector(bmpdata.rect); var palette:Vector.<uint> = pixels.sort(descSort).filter(uniqueSort); trace( vectorColorsToString(palette, 6, "#") ); } private function uniqueSort(item:uint, index:int, vector:Vector.<uint>):Boolean { if (index === 0) return true; return (item !== vector[index - 1]); } private function descSort(x:uint, y:uint):Number { if (x < y) return 1; if (x > y) return -1; return 0; } private function vectorColorsToString(vector:Vector.<uint>, digits:uint = 6, prefix:String = "0x"):Vector.<String> { var colors:Vector.<String> = new Vector.<String>(); for (var i:uint = 0; i < vector.length; i++) { var color:String = vector[i].toString(16); color = "00000000" + color; color = color.substr(color.length - digits, digits); colors.push(prefix + color); } return colors; }
__________________
Reality.getBounds(this); |
|
|||||
|
Регистрация: Jul 2011
Сообщений: 32
|
Да, я пробовал и этим вариантом снимать данные с BitmapData...
Кстати, должен покаяться (как бы ни было досадно это делать) - поторопился отрапортовать, что удовлетворил свой "академический интерес" ... Давно не ощущал себя в такой прострации:чтобы не гонять бессмысленные циклы, изменим , добавим переменную и внутрь var paintBm: trigg = 1 - trigg; var vvv:Vector.<Vector.<Number>> = Vector.<Vector.<Number>>([Vector.<Number>([5, 5, 20, 5, 20, 25, 5, 25, 5, 5]), Vector.<Number>([15, 15, 30, 15, 30, 35, 15, 35, 15, 15])]); tmpSh.graphics.drawPath(commands, vvv[trigg]); trigg:0; color:0xff0000,0xff00ff trigg:1; color:0xff0000 trigg:0; color:0xff0000,0xff00ff Цвета второго прямоугольника игнорированы при любом начальном значении trigg... Однако, если исказим углы прямоугольников var vvv:Vector.<Vector.<Number>> = Vector.<Vector.<Number>>([Vector.<Number>([7, 5, 20, 5, 20, 25, 5, 25, 7, 5]), Vector.<Number>([10, 15, 30, 15, 30, 35, 15, 35, 10, 15])]); trigg:0; color:0xff0000,0xff001f,0xff003f,0xff007f,0xff009f,0xff00bf,0xff00ff trigg:1; color:0xff0000,0xff00df,0xff009f,0xff005f,0xff001f,0xff00ff trigg:0; color:0xff0000,0xff001f,0xff003f,0xff007f,0xff009f,0xff00bf,0xff00ff Попытки отследить связи через отладчик меня не навели ни на какие выводы о причинах такого загадочного поведения... Возможно был недостаточно внимателен, возможно мое знание flash'a and AS изобилует пробелами, что вполне вероятно, т.к. увлекся этим недавно,... но озадачен. Возможно, допускаю некое хулиганство в конструкторе класса, но мне оно не очевидно. Добавлено через 20 часов 4 минуты Если код изменить таким образом public function MyClass() { var thisbitmapdata:BitmapData = new BitmapData(800, 600, true, 0x80FFFFFF); this.bitmapData = thisbitmapdata; var commands:Vector.<int> = Vector.<int>([1, 2, 2, 2, 2]); var data:Vector.<Number> = Vector.<Number>([5, 5, 19, 5, 19, 19, 5, 19, 5, 5]); var i:int = 0; var pixelValue:uint = 0; var paintBm:Function = function(bmp:Bitmap):void { var arr:Vector.<String> = new Vector.<String>(); var tmpSh:Shape = new Shape(); tmpSh.graphics.beginFill(0xFF00FF, 1); tmpSh.graphics.drawPath(commands, data); var r:Rectangle = tmpSh.getBounds(stage); var w:int = r.width; var h:int = r.height; var bmpdata:BitmapData = new BitmapData(w, h, false, 0xFF0000); bmpdata.draw(tmpSh); var mtr:Matrix = new Matrix(1, 0, 0, 1, 30 + i*10, r.topLeft.y); var aSh:Bitmap = new Bitmap(); var aShbmpdata:BitmapData = new BitmapData(w, h, false, 0x00DDCC); for (var m:int = 0; m < w; m++) { for (var j:int = 0; j < h; j++) { pixelValue = bmpdata.getPixel(m, j); if (pixelValue == 0xFF00FF) aShbmpdata.setPixel(m, j, pixelValue); if (arr.length == 0 || arr.indexOf(("0x"+pixelValue.toString(16))) < 0) arr.push("0x"+ pixelValue.toString(16)); } } arr.splice(0, arr.length); aSh.bitmapData = aShbmpdata; bmp.bitmapData.draw(tmpSh); bmp.bitmapData.draw(aSh, mtr, null, null, null, false); tmpSh.graphics.clear(); bmpdata.dispose(); } while(i < 20) { for (var e:int = 0; e < data.length; e++ ) { data[e] += i; } paintBm(this); i +=2; } } |
|
|||||
|
Регистрация: Jul 2011
Сообщений: 32
|
Получить правильные значения адресов пикселей можно таким образом:
но, имхо, это противоречит концепции класса. Пока считаю это багом. Стоит ли использовать, сомневаюсь. Имеются другие мнения? |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
1. Вынесите вложенную функцию. Это – зло в 99% случаев, и лучше так не делать никогда, пока не припрет необходимость.
2. Проблема мне видится в использовании Ректангла, тем более взятого в системе координат стейджа. Я конечно могу ошибаться, ибо код для моего мозга достаточно мутный))))) Вобщем я склонен считать что здесь проблема в тесте, а не баг Адоба. Избавьтесь от ректангла, он тут совершенно не нужен, как я показывал в своем первом посте. Заметьте – это было все, что я изменил в вашем коде, и он заработал.
__________________
Reality.getBounds(this); |
|
|||||
|
Регистрация: Jul 2011
Сообщений: 32
|
1. Предлагаете оформить ее методом класса? Методы класса, имхо, должны отражать существенные особенности класса, а повторяющиеся вычисления удобно помещать в такие функции (это, конечно, частные особенности стиля - кто-то их и никогда не использует). Мнение о том, что вложенные функции "зло", встречал, но язык предусматривает такой прием, хотя для пользы дела, если вот такой "тупик", то можно и просто внутри кода разместить повторяющиеся операции ("раздует" его, правда
).2. В системе координат объекта (самого, содержащего каверзную БитмапДату класса) точно такая же картина - пробовал. Дело в том, что координаты Ректангла дают действительное размещение объекта в стейдже, именно там он и выводится, и там его место, но "мутность" в том, что последним описанным мной способом, я пишу в БитмапДату Фигуру из области, в которой ее нет - вот это меня и удивляет.P.S. Кстати, как "избавиться от Ректангла" - не понимаю. drawPath у меня рисует фигуру, состоящую из многих Безье-кривых, т.е. чтобы получить адреса пикселей, заполняющих фигуру, я этот Ректангл сканирую. Последний раз редактировалось Gantenbain; 03.08.2011 в 19:18. |
|
|||||
|
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Существенные особенности класса отражают его публичные методы. Приватные методы служат нуждам самого класса или его представителя-экземпляра, они инкапсулированы и являются секретом фирмы, так что никаких особенностей отражать не могут – наоборот, являются внутренними методами для операций, нужных данному классу, и только ему. Это чем-то противоречит цели данной функции?
Цитата:
Добавлено через 3 минуты Протрейсите ректангл, может я и зря на него наезжаю, но лучше уж знать, с чем имеем дело. В моем примере с getVector нет вообще никакого ректангла кроме bmpdata.rect - и то лишь потому что его требует метод.
__________________
Reality.getBounds(this); Последний раз редактировалось Wolsh; 03.08.2011 в 20:23. |
|
|||||
|
Регистрация: Jul 2011
Сообщений: 32
|
Цитата:
Цитата:
Разумеется, строить код на противоречащих концепции языка, или на других приемах, в отношении которых, по любым причинам, испытываешь внутреннее сомнение, плохо. Поэтому, для практических целей, вероятно, стоит поэкспериментировать для начала с другими способами создания графического контента фигуры (я не пробовал старые методы moveTo(), lineTo()),- потому что альтернативы BitmapData нет (ByteArray напрямую из фигуры не создашь, и в нем будут только "кривые" пиксели из битмапдаты). Последний раз редактировалось Gantenbain; 04.08.2011 в 10:58. |
![]() |
![]() |
Часовой пояс GMT +4, время: 09:26. |
|
|
« Предыдущая тема | Следующая тема » |
|
|