Сравнение двух растровых изображений друг с другом для сопоставления as3 - PullRequest
1 голос
/ 25 марта 2011

Я пытаюсь расположить изображение поверх другого изображения, основываясь на составе меньшего изображения. Меньшее изображение - это вырез большего изображения, и мне нужно, чтобы оно было расположено точно на большом изображении, чтобы оно выглядело как одно изображение, но с учетом применения отдельных фильтров и альфа-каналов. Поскольку изображения представляют собой не простые прямоугольники или круги, а сложные спутниковые изображения, я не могу просто перерисовать их в коде. У меня есть довольно много изображений, и поэтому я не чувствую, что нужно вручную находить положение каждого изображения и трудно устанавливать их вручную в ActionScript. Можно ли как-нибудь сэмплировать небольшую область размером 5–10 кв. Пикселей на большом изображении и установить значения x и y для меньшего изображения, если будет найдено идеальное совпадение? Все изображения находятся в массиве, и их повторение уже задано, мне просто нужен способ выборки и сопоставления пикселей. Моим первым предположением было зацикливание изображений попиксельно вправо и вниз, охватывая все растровое изображение и переходя к следующему дочернему элементу в массиве, как только найдено совпадение, оставляя сопоставленный дочерний объект таким, каким он был, когда было найдено идеальное совпадение. *

Ответы [ 3 ]

1 голос
/ 25 марта 2011

Вам нужно найти последовательность пикселей на большом изображении.BitmapData.getPixel дает вам значение пикселя.Получите первый пиксель из маленького изображения, найдите его в большом изображении, затем продолжайте сравнение, пока не найдете полное совпадение.Если у вас есть проблемы с кодированием, не стесняйтесь спрашивать.

1 голос
/ 26 марта 2011

Надеюсь, я правильно понял ваш вопрос.

Может быть вариант, который использует copypixels для достижения того, что вы хотите.Вы можете использовать значение bitmapdata.rect, чтобы определить размер сэмпла, который вам нужен, и пройти по большему растровому изображению, используя прямоугольник и движущуюся точку.Давайте посмотрим, смогу ли я это закодировать ...

function findBitmapInBitmap(tinyimg:BitmapData, largeimg:BitmapData):Point {
    var rect:Rectangle = tinyimg.rect;
    var xbound:uint = largeimg.rect.width;
    var ybound:uint = largeimg.rect.height;
    var imgtest:BitmapData = new BitmapData(tinyimg.rect.width, tinyimg.rect.height);

    for (var ypos:uint = 0, y <= ybound, y++) {
        for (var xpos:uint = 0, x <= xbound, x++) {
            imgtest.copyPixels(largeimg, rect, new Point(xpos, ypos);
            if (imgtest.compare(tinyimg) == 0) return new Point(xpos, ypos);
        }
    }

    return new Point(-1,-1); // Dummy value, indicating no match.

}

Что-то в этом роде должно работать - я уверен, что есть место для элегантности кода и возможной оптимизации.Однако, похоже, что этот метод будет очень медленным, так как вам придется проверять каждый пиксель на совпадение.

Есть лучший способ.Разделите ваше большое изображение на слои и используйте технику блитинга для их компоновки во время выполнения.В вашем случае вы можете создать наземную текстуру без спутников, а затем создать спутники отдельно и использовать метод copyPixels, чтобы разместить их там, где вы хотите.Google "блин в as3", чтобы найти хорошие учебники.В настоящее время я работаю над игровым проектом, который использует эту технику, и это очень хороший метод.

Удачи!

Редактировать: Забыли код в выражении возврата по умолчанию.Используя этот метод, вам нужно будет вернуть недопустимую точку (например, (-1, -1)) и проверить ее вне функции.В качестве альтернативы, вы можете просто скопировать свое маленькое растровое изображение в большое в пределах функции, что было бы гораздо более логичным, но я не знаю ваших требований.

1 голос
/ 25 марта 2011

Для фактического сравнения есть BitmapData.compare , который возвращает число 0, если объекты BitmapData эквивалентны.

...