Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Correspondencia entre las coordenadas de ImageView y Pixeles de mapa de bits – Android

En mi aplicación quiero que el usuario pueda seleccionar algún contenido de una imagen contenida dentro de un ImageView .

Para seleccionar el contenido subclase la clase ImageView haciendo que implemente el OnTouchListener para dibujar sobre él un rectángulo con bordes decididos por el usuario.

Aquí hay un ejemplo del resultado del dibujo (para tener una idea de cómo funciona, se puede pensar en él como cuando hace clic con el ratón en el escritorio y arrastra el ratón):

Introduzca aquí la descripción de la imagen

Ahora tengo que determinar qué píxeles de la imagen de Bitmap de Bitmap corresponden a la parte seleccionada. Es fácil determinar cuáles son los puntos de ImageView pertenecientes al rectángulo, pero no sé cómo obtener los píxeles correspondientes, ya que el ImageView tiene una relación de aspecto diferente a la de la imagen original.

He seguido el enfoque descrito especialmente aquí , pero también aquí , pero no estoy totalmente satisfecho porque en mi opinión la correspondencia hecha es 1 en 1 entre píxeles y puntos en el ImageView y no me da todos los píxeles correspondientes a la imagen original a la Área seleccionada.

Llamando hoveredRect el rectángulo en el ImageView los puntos dentro de él son:

 class Point { float x, y; @Override public String toString() { return x + ", " + y; } } Vector<Point> pointsInRect = new Vector<Point>(); for( int x = hoveredRect.left; x <= hoveredRect.right; x++ ){ for( int y = hoveredRect.top; y <= hoveredRect.bottom; y++ ){ Point pointInRect = new Point(); pointInRect.x = x; pointInRect.y = y; pointsInRect.add(pointInRect); } } 

¿Cómo puedo obtener un Vector<Pixels> pixelsInImage contenga los píxeles correspondientes de la imagen de Bitmap de Bitmap ?


EXPLICACIONES AGREGADAS

Voy a explicar un poco mejor el contexto de mi problema:

Tengo que hacer algún procesamiento de imagen en la parte seleccionada, y quiero estar seguro de que todos los píxeles en el rectángulo se procesan.

El procesamiento de la imagen se realizará en un servidor, pero necesita saber exactamente qué píxeles procesar. El servidor trabaja con la imagen con las dimensiones verdaderas, la aplicación android apenas dice qué pixeles procesar al servidor pasando un vector que contiene las coordenadas del pixel

Y por qué no me gustan las soluciones propuestas en los enlaces anteriores:

Las respuestas dadas transforman las coordenadas con una moda de 1 a 1. Este enfoque claramente no es válido para mi tarea, ya que un área de decir 50 puntos en el ImageView de un cierto tamaño en la pantalla no puede corresponder a un área del mismo número de píxeles en la imagen real, pero debe considerar la relación de aspecto diferente .

Como ejemplo, este es el área que debe seleccionarse si la imagen es más pequeña que el ImageView mostrado en la aplicación:

Introduzca aquí la descripción de la imagen

3 Solutions collect form web for “Correspondencia entre las coordenadas de ImageView y Pixeles de mapa de bits – Android”

Matteo,

Parece que esto es más una cuestión de cuánto error puedes tolerar (subjetivamente) en qué píxeles envías al servidor. El hecho es que para cualquier relación de aspecto que no sale a un número entero agradable, usted tiene que decidir qué dirección para 'empujar' su cuadro de selección.

Las soluciones a las que se vinculan son soluciones perfectamente buenas. Tienes que preguntarte: ¿El usuario notará si la imagen que proceso está a un píxel de la caja de selección mostrada en la pantalla? Mi conjetura es probablemente no. No puedo imaginar que el usuario tendrá ese tipo de precisión de píxeles de todos modos al seleccionar un rectángulo con su gran dedo gordo en una pantalla táctil: D

Dado que este es el caso, sólo dejaría que el floor() -ing que se produce cuando el casting a un entero cuidar los píxeles que terminan pasando al servidor.

Veamos un ejemplo.

Vamos a definir el ancho y la altura de nuestro ImageView y Bitmap para ser:

 ImageViewWidth = 400, ImageViewHeight = 150 BitmapWidth = 176, BitmapHeight = 65 

A continuación, las relaciones de aspecto que utilizará para convertir su caja de selección entre ellos serán:

 WidthRatio = BitmapWidth / ImageViewWidth = 175 / 400 = 0.44 HeightRatio = BitmapHeight / ImageViewHeight = 65 / 150 = 0.44 

Algunos números feos. Cualquiera que sea el píxel en el que estoy en el ImageView se corresponderá con un píxel en el mapa de bits de la siguiente manera:

 BitmapPixelX = ImageViewPixelX * WidthRatio BitmapPixelY = ImageViewPixelY * HeightRatio 

Ahora, puse este mapa de bits en la pantalla de mi ImageView para que el usuario seleccione un rectángulo, y el usuario selecciona un rectángulo con las coordenadas superior izquierda e inferior derecha en el ImageView como tal:

 RectTopLeftX = 271, RectTopLeftY = 19 RectBottomRightX = 313, RectBottomRightY = 42 

¿Cómo puedo determinar qué píxeles en el mapa de bits corresponden a? Fácil. Las proporciones que determinamos anteriormente. Echemos un vistazo a las coordenadas de arriba a la izquierda por ahora.

 RectTopLeftX * WidthRatio = 271 * .44 = 119.24 RectTopLeftY * HeightRatio = 19 * .44 = 8.36 

Para RectTopLeftX, nos encontramos en un valor BitmapPixelX de 119, y luego alrededor de un cuarto de una manera en el píxel. Bueno, si tenemos floor() este valor y el valor BitmapPixelY correspondiente de 8.36, enviaremos píxeles (119, 8) al servidor para su procesamiento. Si fuésemos a ceil() estos valores, estaremos enviando píxeles (120, 9) al servidor para su procesamiento. Esta es la parte que depende de usted.

Usted (casi) siempre aterrizará en alguna parte fraccionaria de un píxel. Si envía el píxel en el que aterriza, o el que está al lado de él es su llamada. Yo diría que esto va a ser totalmente imperceptible por su usuario, y por lo tanto, para reiterar, sólo deje que el floor() -ing que se produce cuando el casting a un entero cuidar de él.

¡Espero que ayude!

[EDITAR]

Al leer la pregunta de nuevo más lentamente, creo que mejor entiendo lo que está pidiendo / confuso acerca de. Usaré mi ejemplo para ilustrarlo.

Está diciendo que hay 176 píxeles en el mapa de bits y 400 píxeles en el ImageView. Por lo tanto, la asignación de uno a otro no es 1: 1, y esto causará problemas al determinar qué píxeles para extraer para el procesamiento.

¡Pero no lo hace! Cuando convierte las coordenadas de los límites de rectángulo en ImageView a coordenadas en el mapa de bits, simplemente está dando el rango de píxeles para iterar en el mapa de bits. No es una descripción de cómo cada píxel individual en el ImageView se asigna a un píxel correspondiente en el mapa de bits.

Espero que aclare mi confusión acerca de su confusión.

Esto es solucionable con matemáticas muy simples, su rectángulo tiene 4 puntos p1, p2, p3, p4, con coordenadas x, y, en relación con el ImageView.

También sabes las dimensiones de la imagen original.

Ahora si p1.x, por ejemplo, es 50, en un ImageView que es 200 px de ancho, se obtiene relación de 50/200 = 0.25

Si su imagen original es de 100 px de ancho, su punto p1.x se ubicaría en 100 * 0.25 = 25 px

Se puede expresar:

50 -> 200

? -> 100

Y calculado:

? = 100 * 50/200

Haces esto para cada punto, para cada dimensión x, y, y luego obtienes los 4 puntos del rectángulo en la imagen original.

Ahora si iterar usando estos puntos calculados usted debe conseguir los píxeles del rectángulo en la imagen original.

Aquí estoy asumiendo que usted ha colocado algo dentro de su opinión de la imagen. Haga esto dentro de Creer:

 ImageView image=(ImageView) findViewById(R.id.imageView1); TextView coordinates=(TextView) findViewById(R.id.textView1); bitmap = ((BitmapDrawable)Map.getDrawable()).getBitmap(); 

Y esto en el interiorTouch:

 coordinates.setText("Touch coordinates:"+String.valueOf(event.getX())+"x"+String.valueOf(event.getY())); int pixel = bitmap.getPixel((int)event.getX(), (int)event.getY()); 

Ahora tiene el píxel en particular que desea.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.