|
||
|
![]() |
![]() |
Programación y Desarrollo para Android Subforo exclusivo para temas de programación de software para PDAs y desarrollo de aplicaciones, interfaces, etc bajo Android |
![]() |
|
Herramientas |
#1
|
||||
|
||||
Pintar imagen de forma dinamica
Hola, tal como dice el titulo me gustaria saber como puedo pintar una imagen, no se si habra alguna libreria, un ejemplo de una imagen seria esta:
![]() Pero que pueda hacerlo con una paleta de colores y luego pulsar sobre una zona que quiera pintar, en todo caso que lo haga un niño. Agradesco su ayuda de antemano. |
|
#2
|
||||
|
||||
Por el título pensaba que era otra cosa. Lo que quieres es colorear áreas de una imagen. No es trivial...
Partiendo de que has pulsado en algún punto y que lo blanco es blanco de verdad (un JPG por la compresión podría darte niveles de gris en los bordes y te estropea el invento, un PNG no porque no tiene pérdidas) hay dos opciones principalmente: 1 - A partir de ese punto ir mirando todos los pixeles adyacentes, y los adyacentes de los adyacentes... Si sigue siendo blanco lo coloreas, si es negro dejas de mirar adyacentes (ya has llegado al borde). Computacionalmente puede ser un problema, pero tienes algunas implementaciones de algoritmos algo más rápidas como el FloodFill que presentan aquí. Siempre puedes trabajar con una imagen a menor resolución para que vaya más rápido, pero entonces igual tienes problemas de bordes de sierra. 2 - Yo lo que haría si quisiera hacer un juego de colorear (algún día ![]() El método 1 te ahorra mucho trabajo de crear los mapas de colores, pero tiene varios inconvenientes de rendimiento y un gran problema con algunos dibujos: solo detecta espacios uniformes. En el dibujo que pones, por ejemplo, el brazo doblado corta el ala en dos. Con el método 1 serían dos áreas diferentes, pero en realidad es el ala, debería colorearse entera y dejar el brazo encima como está. Con el mapa de colores las dos partes del ala tendrían el mismo color, con pulsar cualquiera, el ala entera se colorearía. Para el método 2 no sé si habrá alguna biblioteca, se puede hacer en pocas líneas de código (tener los dos Bitmap, consultar color de coordenada en mapa, aplicar máscara, pintar del color que quieras el original), pero hay que leerse muy bien la documentación de las máscaras, filtros, etc., o hacerlo "a lo burro" que es recorrer todos los pixeles y pintarlos uno a uno (altamente ineficiente...). Ya nos dirás qué tal ![]()
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
Gracias de parte de: | ||
#3
|
||||
|
||||
Gracias mocelet, opté por la primera opcion y encontre una libreria, todo va bien a excepcion de el ontouchlistener por que mi bitmap es de 1024x1024 pero el imageview apenas de 300x200 y cuando pulso envia coordenadas erroneas al bitmap y no sé como arreglarlo, gracias por toda la ayuda, te dejo el codigo aqui:
[PHP]package com.example.asd; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.Toast; import com.threekkapps.library.bitmap.JniBitmap; public class MainActivity extends ActionBarActivity implements OnClickListener{ private int[] values; private int x,y; private Bitmap bm; private BitmapDrawable ob; private ImageView IV; @override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); values = new int[2]; IV = (ImageView)findViewById(R.id.IV); // bm = BitmapFactory.decodeResource(getResources(), R.drawable.forme); BitmapDrawable BMD = (BitmapDrawable)IV.getDrawable(); bm = BMD.getBitmap(); ob = new BitmapDrawable(getResources(), bm); IV.setOnClickListener(this); IV.setOnTouchListener(new View.OnTouchListener() { @override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub x=(int) event.getX(); y=(int) event.getY(); return false; } }); } @override public void onClick(View v) { v.getLocationOnScreen(values); switch (v.getId()) { case R.id.IV: BitmapDrawable BMD = (BitmapDrawable)IV.getDrawable(); bm = BMD.getBitmap(); ob = new BitmapDrawable(getResources(), bm); JniBitmap.floodFill(bm,x,y,Color.GREEN,0); IV.setBackgroundDrawable(ob); Toast.makeText(this, x+" "+y, Toast.LENGTH_SHORT).show(); break; default: break; } } @override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } [/PHP] |
#4
|
||||
|
||||
Tienes que calcular el factor de escalado y transformar las coordenadas. Como siempre, en stackoverflow alguien lo ha escrito... http://stackoverflow.com/questions/4...-of-the-bitmap
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
Gracias de parte de: | ||
#5
|
||||
|
||||
Tienes que calcular el factor de escalado y transformar las coordenadas. Como siempre, en stackoverflow alguien lo ha escrito... http://stackoverflow.com/questions/4...-of-the-bitmap
![]() [PHP]package com.example.asd; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.Toast; import com.threekkapps.library.bitmap.JniBitmap; public class MainActivity extends ActionBarActivity implements OnClickListener{ private int[] values; private int x,y; private Bitmap bm; private BitmapDrawable ob; private ImageView IV; private int originalImageOffsetX, originalImageOffsetY; @override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); values = new int[2]; IV = (ImageView)findViewById(R.id.IV); // bm = BitmapFactory.decodeResource(getResources(), R.drawable.forme); BitmapDrawable BMD = (BitmapDrawable) IV.getDrawable(); bm = BMD.getBitmap(); ob = new BitmapDrawable(getResources(), bm); IV.setOnClickListener(this); IV.setOnTouchListener(new View.OnTouchListener() { @override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub x=(int) event.getX(); y=(int) event.getY(); ////////////////////////////////////////////////////// ImageView imageView = (ImageView)findViewById(R.id.IV); Drawable drawable = imageView.getDrawable(); Rect imageBounds = drawable.getBounds(); //original height and width of the bitmap int intrinsicHeight = drawable.getIntrinsicHeight(); int intrinsicWidth = drawable.getIntrinsicWidth(); //height and width of the visible (scaled) image int scaledHeight = imageBounds.height(); int scaledWidth = imageBounds.width(); //Find the ratio of the original image to the scaled image //Should normally be equal unless a disproportionate scaling //(e.g. fitXY) is used. float heightRatio = intrinsicHeight / scaledHeight; float widthRatio = intrinsicWidth / scaledWidth; //do whatever magic to get your touch point //MotionEvent event; //get the distance from the left and top of the image bounds int scaledImageOffsetX = (int) (event.getX() - imageBounds.left); int scaledImageOffsetY = (int) (event.getY() - imageBounds.top); //scale these distances according to the ratio of your scaling //For example, if the original image is 1.5x the size of the scaled //image, and your offset is (10, 20), your original image offset //values should be (15, 30). originalImageOffsetX = (int) (scaledImageOffsetX * widthRatio); originalImageOffsetY = (int) (scaledImageOffsetY * heightRatio); Toast.makeText(getApplicationContext(), originalImageOffsetX+" "+originalImageOffsetY+" "+heightRatio+" "+widthRatio, Toast.LENGTH_SHORT).show(); ////////////////////////////////////////////////////// return false; } }); } @override public void onClick(View v) { v.getLocationOnScreen(values); switch (v.getId()) { case R.id.IV: BitmapDrawable BMD = (BitmapDrawable)IV.getDrawable(); bm = BMD.getBitmap(); ob = new BitmapDrawable(getResources(), bm); JniBitmap.floodFill(bm,originalImageOffsetX,origin alImageOffsetY,Color.GREEN,0); IV.setBackgroundDrawable(ob); Toast.makeText(this, x+" "+y, Toast.LENGTH_SHORT).show(); break; default: break; } } @override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } [/PHP] |
#6
|
||||
|
||||
Hay dos aspectos que tienes que probar por separado:
1 - ¿Falla el cálculo del punto? (ya que tienes un toast, puedes mirar si los valores son correctos) 2 - Si especificas el punto "a mano", ¿se pinta bien o tampoco? (en ese caso el problema no es del cálculo sino del pintado)
__________________
El mejor Cuatro en Raya de Android (Hilo en HTCMania, Play Store) ¡Un millón de descargas!
|
Gracias de parte de: | ||
#7
|
||||
|
||||
Es el calculo el que falla no el pintado, el pintado va de maravilla si las coordenadas las pongo de manera fija y no dinamica como extraer los puntos, no se como hacer para que calcule de manera correcta ¿Qué es lo que estoy haciendo mal?, gracias de nuevo Mocelet.
|
![]() |
![]() |
||||||
|