让我解释一下这是什么意思:
首先有两个具有相同尺寸的图像视图,第一个是掩模,它在第二个是重叠的照片上。
pusdeo布局
<RelativeLayout>
<image view (mask) match parent>
<image view (photo) match parent>
</RelativeLayout>
因此,当应用程序启动时,它是一个完整的黑暗页面。然后用户开始在屏幕上拖动,就像扫出面具并在面具后面显示照片一样。样本照片是这样的:
只需将焦点放在顶部图像上,就像这样,照片顶部有一个遮罩,只有当用户在屏幕上拖动时,它才会清洁遮罩并显示背后的照片。如何实现这一点,我是否需要使用cavans /其他库?
感谢您的帮助
答案 0 :(得分:4)
这是一个代码示例。重要的部分是1)它使用与图像视图重叠的自定义视图; 2)它使用位图画布进行实际绘制(为了能够清除像素所需); 3)绘画使用特殊的CLEAR
转移模式。
package com.example.drawingwithmask;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class DrawView extends View implements OnTouchListener {
private Paint bmPaint = new Paint();
private Paint drawPaint = new Paint();
private Path path = new Path();
private Canvas cv = null;
private Bitmap bm = null;
private boolean firstTimeThru = true;
public DrawView(Context context) {
super(context);
init();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void init() {
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
}
@Override
public void onDraw(Canvas canvas) {
// Set everything up the first time anything gets drawn:
if (firstTimeThru) {
firstTimeThru = false;
// Just quickly fill the view with a black mask:
canvas.drawColor(Color.BLACK);
// Create a new bitmap and canvas and fill it with a black mask:
bm = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888);
cv = new Canvas();
cv.setBitmap(bm);
cv.drawColor(Color.BLACK);
// Specify that painting will be with fat strokes:
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeWidth(canvas.getWidth() / 15);
// Specify that painting will clear the pixels instead of paining new ones:
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
cv.drawPath(path, drawPaint);
canvas.drawBitmap(bm, 0, 0, bmPaint);
super.onDraw(canvas);
}
public boolean onTouch(View view, MotionEvent event) {
float xPos = event.getX();
float yPos = event.getY();
switch (event.getAction()) {
// Set the starting position of a new line:
case MotionEvent.ACTION_DOWN:
path.moveTo(xPos, yPos);
return true;
// Draw a line to the ending position:
case MotionEvent.ACTION_MOVE:
path.lineTo(xPos, yPos);
break;
default:
return false;
}
// Call onDraw() to redraw the whole view:
invalidate();
return true;}
}
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher" />
<com.example.drawingwithmask.DrawView
android:id="@+id/draw"
android:layout_width="match_parent"
android:layout_height="match_parent" />
package com.example.drawingwithmask;
import android.app.Activity; import android.os.Bundle;
public class MainActivity extends Activity {
DrawView drawView = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
drawView = (DrawView) findViewById(R.id.draw);
}
}
这是一种可以估算是否已达到某个掩模清除阈值的方法。我通过调用checkProgress()
事件案例中的MOTION_MOVE
对其进行了测试。这可能不是最好的方式,或者甚至可能是一种好方法,但它至少以牺牲STEPS ^ 2(如所示的400)像素检查为代价来提供估计。
final int STEPS = 20;
final double THRESHOLD = 0.70;
private void checkProgress() {
int sum = 0;
for (int x = 0; x < bm.getWidth(); x += bm.getWidth() / STEPS)
for (int y = 0; y < bm.getHeight(); y += bm.getHeight() / STEPS)
if (bm.getPixel(x, y) != Color.BLACK)
sum++;
double progress = (double) sum / (STEPS * STEPS);
Log.v(TAG, "Cleared: " + progress);
if (progress >= THRESHOLD)
Log.i(TAG, "Done!");
}