Flex — Как подсчитать цвета в векторном файле .SWF

Предположим, я преобразовал файл векторного изображения (.AI/.SVG) в .SWF для простоты динамического импорта в качестве источника изображения во Flex.

Чтобы теперь подсчитать цвета, мне нужно создать «новый BitMap», затем «.draw()», перебрать все пиксели и использовать «.getPixel()» для получения цвета.

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

Есть ли лучшая альтернатива этому во Flex?


person Eric    schedule 08.01.2010    source источник
comment
может это предварительный этап?   -  person jedierikb    schedule 09.01.2010


Ответы (3)


У меня есть решение, но оно может быть не самым лучшим. По сути, я просто перебираю байты swf, используя as3swf, и ищу определения формы, а затем перехожу к заливке. . Оттуда я помещаю цвета (сплошные заливки и цвета, найденные в градиентах) в массив. Поскольку могут быть дубликаты, я удаляю их в конце.

Вот код:

import com.codeazur.as3swf.*;
import com.codeazur.as3swf.tags.*;

var colors:Array = [];
var colorsNum:int = 0;
var request:URLRequest = new URLRequest("plank.swf");
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, completeHandler);
loader.load(request);

function completeHandler(e:Event):void {
    var swf:SWF = new SWF(URLLoader(e.target).data as ByteArray);
    var tagsNum:int = swf.tags.length;
    for(var i:int = 0 ; i < tagsNum ; i++){
        if(swf.tags[i].name.substr(0,11) == 'DefineShape'){
            var fillStylesNum:int = TagDefineShape4(swf.tags[i]).shapes.fillStyles.length;
            if(fillStylesNum > 0){
                for(var j:int = 0 ; j < fillStylesNum ; j++){
                    if(TagDefineShape4(swf.tags[i]).shapes.fillStyles[j].gradient){
                        var recordsNum:int = TagDefineShape4(swf.tags[i]).shapes.fillStyles[j].gradient.records.length;
                        for(var k:int = 0 ; k < recordsNum; k++){}
                            colors.push(TagDefineShape4(swf.tags[i]).shapes.fillStyles[j].gradient.records[k].color)
                    }else{
                        colors.push(TagDefineShape4(swf.tags[i]).shapes.fillStyles[j].rgb);
                    }
                }
            }
        }
    }
    colors.sort(Array.NUMERIC);
    removeDuplicates(colors);
    trace('numColors: ' + colors.length + '\ncolors: ' + colors);
}
function removeDuplicates(array:Array):Array{
    var length:int = array.length;
    var i:int, j:int;
    var newLength:int = 1;

    for(i=1; i< length; i++){

       for(j=0; j< newLength ; j++)
       {

          if(array[i] == array[j])
          break;
       }
        if (j==newLength )
          array[newLength++] = array[i];
    }
    array.length = newLength;
    return array;
}

ХТН

person George Profenza    schedule 09.01.2010
comment
Удивительно, но на самом деле это было намного быстрее, чем обработка каждого пикселя в массиве BitMapData. Спасибо за предложение! - person Eric; 31.01.2010

Чтобы избавиться от векторного сглаживания, вы можете установить для свойства stage.quality значение StageQuality.LOW, прежде чем рисовать его в BitmapData, это может помочь.

Это, безусловно, будет сложнее, но для ускорения вашего алгоритма вы, вероятно, могли бы заставить PixelBender или Alchemy выполнить эту работу.

person Zed-K    schedule 28.01.2010
comment
Отметил это как ответ, так как это работает. Попытка решить проблему, когда пользователь видит изменение качества во время подсчета цветов, а затем обратно. Спасибо! - person Eric; 31.01.2010

Попробуйте использовать ConvolutionFilter, чтобы повысить резкость исходного векторного изображения. Возможно, вам придется настроить матрицу фильтра, чтобы получить правильные значения для повышения резкости сглаживания. Затем выполните метод BitmapData.draw() для изображения, чтобы просмотреть пиксели и данные пикселей. Повышение резкости исходного вектора позволит обнаружить очень маленькие цветные области; если вы увеличиваете резкость объекта Bitmap после draw(), цвета этих небольших областей могут отображаться как немного отличающиеся от исходного цвета.

person wpjmurray    schedule 08.01.2010