Hola, llevo unos días buscando datos sobre un filtro. Necesito convertir una imagen de un mapa polar en un mapa cardinal normal. La idea es contrastar la deformación entre los 2 a partir de un filtro de exclusión que indique los errores entre ambos.
Mi problema esta cuando intento modificar el bitmapData, el cual lo hago a partir de 2 for que recorren el documento pixel por pixel. He usado un "Point.polar" para calcular donde escribir el pixel de destino, pero parece que tarda demasiado y no permite terminar de ejecutar. Tambien he usado http://www.actionscript.org/forums/showpost.php3?p=687913&postcount=5 para hacerlo y dice lo mismo.
Las capturas pixel a pixel tardan bastante tiempo, y pueden dar timeout en capturas dentro de dos for. Lo que te recomiendo es que uses un setInterval o un onEnterFrame para ir capturando todo y pasarlo, de esta forma evitas que el archivo de timeout, especialmente si tus bitmaps son grandes (es decir, la operación tarda más de 30 segundos)
hola Jorge, lo que dices es cierto pero necesito pasar toda la imagen al iniciar el script (es todo lo que va a hacer).
He encontrado varios codigos que pasan de una imagen rectangular o cuadrada a una polar, pero los mejores creo que fueron estos de blitzagency.
Lo que estoy intentando es usar el archivo .as de la deformación como base para invertir el resultado pero me salen un poco raro.
Dejo la modificación base del archivo PolarCoordinates.as
Código :
package com.blitzagency.filters{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.*;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.geom.Matrix;
public class PolarCoordinates{
public function PolarCoordinates(){}
public static function convertBitmapData(image:BitmapData):BitmapData{
var imageWidth:Number = image.width;
var imageHeight:Number = image.height;
//var radius:Number = imageWidth/2;
var xCenter:Number = (imageWidth/2); //Math.round(imageWidth/2);
var yCenter:Number = (imageHeight/2); //Math.round(imageHeight/2);
var referencia:Point = new Point(xCenter , yCenter);
var polarBitmap:BitmapData = new BitmapData(imageWidth,imageHeight,true,0x00000000);
for( var yPos:Number=0; yPos<imageHeight; yPos++ ){
for(var xPos:Number=0; xPos<imageWidth; xPos++ ){
var cartesian:Point = new Point(xPos,yPos);
var angulo:Number = Math.atan2(yPos, xPos);
var distancia = Point.distance(referencia, cartesian);
var polarpix = Point.polar(distancia, angulo);
var color:uint = image.getPixel32(xPos,yPos);
polarBitmap.setPixel32(polarpix['x'],polarpix['y'],color);
}
}
return polarBitmap;
}
}
}
Fíjate que lógicamente está basado en dos for que capturan pixel a pixel, y allí es donde da el timeout, Por eso te sugerí que lo conviertas en un setinterval con dos contadores que se incrementen (para file-columna)
Muchas gracias por seguir el hilo Jorge, pero la verdad es que por ahora y mientras siga funcionando mejor no lo toco Lo que sigue sin funcionarme es hacer la distorsión polar. He probado a obtener los puntos con Point.Polar() y el resultado que obtengo es que el vértice de inicio de la distorsión polar en vez de estar en el centro de la imagen me lo pone en el punto (0,0). ¿Alguna idea de como podría poner el punto de origen de la distorsión polar en el centro?
Me parece que la mejor manera es escoger el punto del medio Math.floor(ancho/2) , Math.floor(alto/2) y empezar a escoger, en el caso de la horizontal, primero a la izquierda y despues a la dercha los pixeles y en el caso de la vertical primero arriba y despues abajo.
Cierto elchininet, esque modifique el codigo y no he tenido oportunidad de ponerlo hasta ahora.
Solucione lo que comentas haciendo que los for no funcionen cardinalmente si no polar mente. he echo que uno recorra 360º y el otro pixel a pixella distancia entre el centro y el extremo de la imagen.
El primer problema fue que me leia los pixel radialmente desde el punto (0,0) cardinal del MC de origen, y eso hacia que me salieran cosas muy raras. Fue cuando decidi hacer que los datos del bitmap dejasen de mostrarse en cardinal como prueba para poder verlo mejor (de haí que en los ejemplos que os pongo abajo salga el resultado en circulo y no en linea como pretendo). Esto lo solucione a mano, moviendo los objetos de dentro del MC de origen, pero el Bitmap se crea dinamicamente, por lo que no encuentro forma de hacer que en vez de comenzar a escribir en el (0,0) comience en el punto centro. La unica solucion que se me ocurrio es sumarle al punto de escritura original la mitad en ancho y en alto... pero no funciona muy bien.
yap, he estado pensando en deformaciones parciales... (me explico)
habia pensado cortar la imagen en 4 partes, dejando 90º de cada pedazo del mapa y aplicarles con una matriz un giro para que se queden todos orientados hacia el mismo sitio (con los 0º en horizontal). Una vez echo esto, había penado usar una distorsión DisplacementMapFilters como en este ejemplo pero no hay manera de encontrar documentación o saber mas o menos como usarlo
Por lo que he visto creo q funciona a partir de una mascara de color degradado que es interpretada a modo de lente que distorsiona los pixel, pero no comprendo muy bien como funciona...
os dejo también el ejemplo de la pagina para ver si os suena..
(con la ruleta del ratón, en este ejemplo se puede aumentar o disminuir el ancho del circulo..)
Buenas chicos. El ejemplo del comentario anterior aun no lo he logrado descifrar por completo (todavía no se como logra hacer esa deformación tan radical) pero he seguido en la misma linea.
No hace falta que se realice una transformación total en un paso claramente... yo me conformo con obtener 1/4 de la imagen de arriba ya que luego se puede a partir de cortar porciones de la imagen polar ir haciendo las deformaciones por separado, pero aunque seguiré intentando me parece que algo se me escapa.