2016-11-18 10 views
0

Я хотел бы создать эффект кисти, который, когда пользователь тащит его/ее палец на экране, кисть меняет только альфа изображения/растрового изображения ниже. Например, если непрозрачность щетки установлена ​​на 50%, то при нанесении щетки должно бытьИзменение прозрачности для Android только в области растрового изображения

  1. Установите альфа/непрозрачность этой области, только этот регион не весь растровый рисунок.
  2. Оставьте базовые цвета растровой области неизменными.

То есть кисть должна влиять только на альфа-прозрачность, а не на цвет. Я начинаю со следующего кода:

public class DrawingView extends View { 

    //drawing path 
    private Path drawPath; 
    //drawing and canvas paint 
    private Paint drawPaint, canvasPaint; 
    //initial color 
    private int paintColor = 0xFFFF0000, paintAlpha = 255; 
    //canvas 
    private Canvas drawCanvas; 
    //canvas bitmap 
    private Bitmap canvasBitmap; 

    //constructor 
    public DrawingView(Context context, AttributeSet attrs){ 
     super(context, attrs); 
     setupDrawing(); 
    } 

    //prepare drawing 
    private void setupDrawing(){ 
     drawPath = new Path(); 
     drawPaint = new Paint(); 
     drawPaint.setColor(paintColor); 
     drawPaint.setAntiAlias(true); 
     drawPaint.setStrokeWidth(50); 
     drawPaint.setStyle(Paint.Style.STROKE); 
     drawPaint.setStrokeJoin(Paint.Join.ROUND); 
     drawPaint.setStrokeCap(Paint.Cap.ROUND); 
     canvasPaint = new Paint(Paint.DITHER_FLAG); 
    } 

    //view assigned size 
    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     drawCanvas = new Canvas(canvasBitmap); 
    } 

    //draw view 
    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); 
     canvas.drawPath(drawPath, drawPaint); 
    } 

    //respond to touch interaction 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     float touchX = event.getX(); 
     float touchY = event.getY(); 
     //respond to down, move and up events 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      drawPath.moveTo(touchX, touchY); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      drawPath.lineTo(touchX, touchY); 
      break; 
     case MotionEvent.ACTION_UP: 
      drawPath.lineTo(touchX, touchY); 
      drawCanvas.drawPath(drawPath, drawPaint); 
      drawPath.reset(); 
      break; 
     default: 
      return false; 
     } 
     //redraw 
     invalidate(); 
     return true; 
    } 

    //return current alpha 
    public int getPaintAlpha(){ 
     return Math.round((float)paintAlpha/255*100); 
    } 

    //set alpha 
    public void setPaintAlpha(int newAlpha){ 
     paintAlpha=Math.round((float)newAlpha/100*255); 
     drawPaint.setColor(paintColor); 
     drawPaint.setAlpha(paintAlpha); 
    } 
} 

Как вы заметили, эта кисть должна иметь цвет заливки. Этого хотят избежать. Мне нужна кисть с прозрачностью, но не цвет.

Если есть другой способ достижения объекта, это нормально.

ответ

0

Установка абсолютного значения альфа-сигнала, вероятно, будет связана с некоторым смещением пикселей в растровом изображении.

Самый близкий режим Porter-Duff для того, что вы хотите, это DST_OUT, который будет действовать как ластик.

Попробуйте этот код и посмотреть, если он приближается:

 drawPaint.setColor(Color.BLACK); // the color doesn't really matter 
     drawPaint.setAlpha(255 - alpha); // inverse of the alpha result you want 
     drawPaint.setXferMode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); 

Что это будет сделать, это сделать пиксели изображения светлее и светлее, каждый раз, когда вы рисуете по тому же месту, что, вероятно, не то, что вы хотите. В этом случае вам придется усложняться и рисовать цветные + альфа-пути на отдельном растровом изображении, затем нарисуйте , чтобы растровое изображение по вашему растровому изображению с использованием PorterDuff.Mode.DST_OUT.

Прискорбно, что вы не можете просто реализовать пользовательский ColorFilter, который будет делать именно то, что вы хотите. Все эти графические операции происходят в родном пространстве, и Google не хочет, чтобы мы просто смертные возились с этим материалом.