Android Paint: cómo obtener efecto "aerógrafo"?
Hola y gracias por su ayuda.
Por favor, estoy siguiendo la demostración "FingerPaint" en las demostraciones API.
- Android Webview: No se puede llamar a determinedVisibility () - nunca vio una conexión para el pid
- Cifrar y descifrar xml
- Cómo seleccionar valores aleatorios de un rango dado
- Convertir byte en Tipo de búfer
- Detenga el subproceso Java que llama a la función JNI
Por favor necesitaría un efecto de "aerógrafo", en el sentido de que cuando dibujo sobre el mismo lugar se vuelve más oscuro y oscuro.
Por favor vea la imagen:
Como se puede ver el centro es más oscuro porque pasé con la pintura en el mismo lugar más de una vez.
¿Por favor cómo obtengo el mismo efecto, de conseguir un punto más oscuro si es dibujado sobre más de una vez?
¡Gracias!
EDIT EDIT EDIT
Lo sugerido
mPaint.setAlpha(0x80)
Tipo de trabajo, pero sólo si suelto el tacto y luego toque de nuevo, si no suelto y mantener el dedo en la pantalla el efecto no se alcanza.
El punto es que no alcanzas el efecto si no sueltas el dedo de la pantalla, si sigues dibujando sin soltar el tacto no se oscurece cuando la pintura termina. Si sueltas el tacto y luego dibujas de nuevo, obtienes el efecto
Este es el resultado que obtengo. Y yo no quiero:
Este sería el resultado deseado:
Este es el código tomado de la API Demos:
public class FingerPaint extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(0x44FF0000); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(12); } private Paint mPaint; public class MyView extends View { private static final float MINP = 0.25f; private static final float MAXP = 0.75f; private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mBitmapPaint; public MyView(Context c) { super(c); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFAAAAAA); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); canvas.drawPath(mPath, mPaint); } private float mX, mY; private static final float TOUCH_TOLERANCE = 4; private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; } } private void touch_up() { mPath.lineTo(mX, mY); // commit the path to our offscreen mCanvas.drawPath(mPath, mPaint); // kill this so we don't double draw mPath.reset(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } } }
- Acerca de los nuevos métodos y métodos obsoletos en las API de Android
- Android Studio Gradle proyecto "No se puede iniciar el proceso de daemon / inicialización de VM"
- La aplicación de Android se bloquea después de integrar React Native con NoClassDefFoundError: com.facebook.react.bridge.JSPackagerWebSocketClient
- Java (Android) Insertar icono en lienzo
- RelativeLayout con MATCH_PARENT no funciona
- Ejecución de pruebas de instrumentación desde un paquete específico mediante un complemento de cuchara-gradle
- Sombra larga de Android TextView
- No se puede encontrar el paquete de licencias de Google Market en SDK Manager
Hice sólo algunos cambios menores en su código.
mPaint.setColor(Color.BLACK);// changed color to balck mPaint.setAlpha(0x80); // only change
Clase de actividad
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(Color.BLACK); mPaint.setAlpha(0x80); // only change mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(12); } private Paint mPaint; public class MyView extends View { private static final float MINP = 0.25f; private static final float MAXP = 0.75f; private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mBitmapPaint; public MyView(Context c) { super(c); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFAAAAAA); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); canvas.drawPath(mPath, mPaint); } private float mX, mY; private static final float TOUCH_TOLERANCE = 4; private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2); mX = x; mY = y; } } private void touch_up() { mPath.lineTo(mX, mY); // commit the path to our offscreen mCanvas.drawPath(mPath, mPaint); // kill this so we don't double draw mPath.reset(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } } }
Tiro rápido
Este enfoque es más de una simulación la forma en que algo como Photoshop lo haría: Integrar a lo largo de la trayectoria y dibujar salpicaduras de pintura individuales con un espaciado ajustable entre.
public class DrawView extends View { public Paint mPaint; private Bitmap mBitmap; private Canvas mCanvas; private int strokeRadius; private ShapeDrawable mBrush; private Paint mBitmapPaint; private float mPreviousX, mPreviousY; public DrawView(Context context, AttributeSet attrs) { super( context, attrs); mBitmapPaint = new Paint(Paint.DITHER_FLAG); int strokeWidth = 20; strokeRadius = strokeWidth/2; Shape brushShape = new OvalShape(); mBrush = new ShapeDrawable(brushShape); Paint paint = mBrush.getPaint(); // radial gradient shader with a transparency falloff, if you don't want this, // just set a color on the paint and remove the setShader call Shader shader = new RadialGradient(strokeRadius, strokeRadius, strokeRadius, Color.argb(255, 0, 0, 0), Color.argb(0, 0, 0, 0), Shader.TileMode.CLAMP); paint.setShader(shader); paint.setAlpha(0x10); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFF00B8F5); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); } private void touch_start(float x, float y) { mPreviousX = x; mPreviousY = y; } private void touch_move(MotionEvent event) { float x = event.getX(); float y = event.getY(); // get vector from previous to current position float xdist = x - mPreviousX; float ydist = y - mPreviousY; // get the length float segmentLength = (float) Math.sqrt(xdist * xdist + ydist * ydist); // derive a suitable step size from stroke width float stepSize = Math.max(strokeRadius / 10, 1f); // calculate the number of steps we need to take // NOTE: this draws a bunch of evenly spaced splashes from the start point // to JUST BEFORE the end point. The end point will be drawn by the start point of the // next stroke, or by the touch_up method. If we drew both the start and // end point there it would be doubled up int steps = Math.max(Math.round(segmentLength / stepSize), 2); for(int i = 0; i < steps; ++i) { int currentX = (int) (mPreviousX + xdist * i / steps); int currentY = (int) (mPreviousY + ydist * i / steps); drawSplash(currentX, currentY); } // update the previous position mPreviousX = x; mPreviousY = y; } private void touch_up(MotionEvent event) { drawSplash((int) event.getX(), (int)event.getY()); } /** * draws the brush to the canvas, centered around x and y * @param x * @param y */ private void drawSplash(int x, int y) { mBrush.setBounds(x - strokeRadius, y - strokeRadius, x + strokeRadius, y + strokeRadius); mBrush.draw(mCanvas); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(event); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(event); invalidate(); break; } return true; } }
Editar: disparo instantáneo (Raghunandan). Prueba del resultado con el fondo blanco y la pintura negra del color.
Encontré la solución. Para aquellos que puedan estar interesados:
public class DrawView extends View { public Paint mPaint; private Paint mPaint1; private Paint mPaint2; private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mBitmapPaint; public DrawView(Context context, AttributeSet attrs) { super( context, attrs); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); mPaint = new Paint(); mPaint.setAlpha(0x80); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setColor(0x44000000); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.BUTT); mPaint.setStrokeWidth(5); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); mCanvas = new Canvas(mBitmap); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFF00B8F5); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); } private float mX, mY; private static final float TOUCH_TOLERANCE = 4; private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; //mCanvas.drawPoint(x, y, mPaint); } private void touch_move(MotionEvent event) { float x = event.getX(); float y = event.getY(); Path npath=new Path(); npath.moveTo(mX, mY); npath.lineTo( x ,y ); mX=x; mY=y; mCanvas.drawPath(npath, mPaint); npath.reset(); //Log.e("","sto disegando"); } private void touch_up() { } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(event); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } }
Editar: Adjuntar una foto instantánea de mi emulador (Raghunandan). He utilizado su código sin cambios, excepto el aumento de la anchura de trazo y se ve como a continuación.
No se ve bien cuando dibujas lentamente.
La anchura de trazo de disparo de pantalla 12 si dibuja una línea striaght no hay problema. Pero cuando dibujas zig zag puedes ver que no se ve bien
- VerifyError en las herramientas de compilación del proyecto de prueba android v17
- ¿Existe una manera de implementar en caliente los cambios delta en un dispositivo Android?