Android在画布上操纵图像 - 使用触摸,移动,放大/缩小,缩放

曾无好事来相访,赖尔高文一起予。这篇文章主要讲述Android在画布上操纵图像 - 使用触摸,移动,放大/缩小,缩放相关的知识,希望能为你提供帮助。
我正在研究这样的摄影应用程序:https://play.google.com/store/apps/details?id=com.photo.editor.collage.maker.photoblender& hl=en
我必须实现这样的功能:
【Android在画布上操纵图像 - 使用触摸,移动,放大/缩小,缩放】这个视图我有2个功能......
1)具有飞溅背景

2)背景模糊

两者都使用2个形状....现在你正在使用路径绘制形状....我想绘制像上面的图像位图形状。
我有更多的形状如下(所有有2个图像如上):
3)

我想替换您正在使用的这部分代码:

private void createPath() { path.reset(); path.moveTo(114, 156); float[] points = {68, 138, 19, 136, 21, 87, 8, 39, 56, 26, 97, -2, 123, 40, 163, 71, 131, 109}; for (int i = 0; i < points.length; i += 2) { path.lineTo(points[i], points[i + 1]); } path.close(); Matrix m = new Matrix(); m.setRectToRect(new RectF(0, 0, 160, 160), clip, Matrix.ScaleToFit.CENTER); path.transform(m); transformedPath.set(path); }

我通过添加形状作为路径做了上述功能,但是当我尝试使用形状作为位图时,我没有得到完整的结果....这里是我的视图代码。
class MotionImageView extends View implements MatrixGestureDetector.OnMatrixChangeListener { private final Bitmap shapeMaskBitmap; private final Bitmap shapeShadowBitmap; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); Paint monoPaint = new Paint(Paint.ANTI_ALIAS_FLAG); Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); Bitmap bitmap, blur; Matrix matrix = new Matrix(); Matrix pathMatrix = new Matrix(); //Path path = new Path(); //Path transformedPath = new Path(); MatrixGestureDetector detector; RectF clip = new RectF(); public MotionImageView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); Log.e("~~~~", "1111"); bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.model); blur = blur(context, bitmap, 8); ColorMatrix cm = new ColorMatrix(); cm.setSaturation(0.25f); monoPaint.setColorFilter(new ColorMatrixColorFilter(cm)); borderPaint.setStyle(Paint.Style.STROKE); borderPaint.setColor(0xccffffff); borderPaint.setStrokeWidth(4); borderPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); detector = new MatrixGestureDetector(pathMatrix, this); shapeMaskBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.shape_mask); shapeShadowBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.shape_shadow); }@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Shader shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); RectF src = https://www.songbingjia.com/android/new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); RectF dst = new RectF(0, 0, w, h); matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); shader.setLocalMatrix(matrix); paint.setShader(shader); matrix.mapRect(clip, src); //createPath(); }/*private void createPath() { path.reset(); path.moveTo(114, 156); float[] points = {68, 138, 19, 136, 21, 87, 8, 39, 56, 26, 97, -2, 123, 40, 163, 71, 131, 109}; for (int i = 0; i < points.length; i += 2) { path.lineTo(points[i], points[i + 1]); } path.close(); Matrix m = new Matrix(); m.setRectToRect(new RectF(0, 0, 160, 160), clip, Matrix.ScaleToFit.CENTER); path.transform(m); transformedPath.set(path); }*/@Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(blur, matrix, monoPaint); canvas.save(); canvas.clipRect(clip); //canvas.drawPath(transformedPath, paint); canvas.drawBitmap(shapeMaskBitmap, pathMatrix, paint); canvas.restore(); //canvas.drawPath(transformedPath, borderPaint); canvas.drawBitmap(shapeShadowBitmap, pathMatrix, borderPaint); }@Override public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); return true; }@Override public void onChange(Matrix matrix) { //path.transform(matrix, transformedPath); pathMatrix.set(matrix); invalidate(); }Bitmap blur(Context ctx, Bitmap src, float radius) { Bitmap bitmap = src.copy(src.getConfig(), true); RenderScript renderScript = RenderScript.create(ctx); Allocation blurInput = Allocation.createFromBitmap(renderScript, src); Allocation blurOutput = Allocation.createFromBitmap(renderScript, bitmap); ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript)); blur.setInput(blurInput); blur.setRadius(radius); blur.forEach(blurOutput); blurOutput.copyTo(bitmap); renderScript.destroy(); return bitmap; } }

我的输出是这样的:

答案你想用PorterDuff.Mode.CLEARBlurMaskFilter做什么不会起作用,如果你想要这样的效果:
Android在画布上操纵图像 - 使用触摸,移动,放大/缩小,缩放

文章图片

或这个:
Android在画布上操纵图像 - 使用触摸,移动,放大/缩小,缩放

文章图片

你必须使用BitmapShaderScriptIntrinsicBlur,请参阅此示例自定义View
class V extends View implements MatrixGestureDetector.OnMatrixChangeListener { Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); Paint monoPaint = new Paint(Paint.ANTI_ALIAS_FLAG); Paint borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); Bitmap bitmap, blur; Matrix matrix = new Matrix(); Matrix pathMatrix = new Matrix(); Path path = new Path(); Path transformedPath = new Path(); MatrixGestureDetector detector; RectF clip = new RectF(); public V(Context context) { super(context); bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.forest); blur = blur(context, bitmap, 8); ColorMatrix cm = new ColorMatrix(); cm.setSaturation(0.25f); monoPaint.setColorFilter(new ColorMatrixColorFilter(cm)); borderPaint.setStyle(Paint.Style.STROKE); borderPaint.setColor(0xccffffff); borderPaint.setStrokeWidth(4); detector = new MatrixGestureDetector(pathMatrix, this); }@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Shader shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); RectF src = https://www.songbingjia.com/android/new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); RectF dst = new RectF(0, 0, w, h); matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); shader.setLocalMatrix(matrix); paint.setShader(shader); matrix.mapRect(clip, src); createPath(); }private void createPath() { path.reset(); path.moveTo(114, 156); float[] points = {68, 138, 19, 136, 21, 87, 8, 39, 56, 26, 97, -2, 123, 40, 163, 71, 131, 109}; for (int i = 0; i < points.length; i += 2) { path.lineTo(points[i], points[i + 1]); } path.close(); Matrix m = new Matrix(); m.setRectToRect(new RectF(0, 0, 160, 160), clip, Matrix.ScaleToFit.CENTER); path.transform(m); transformedPath.set(path); }@Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(blur, matrix, monoPaint); canvas.save(); canvas.clipRect(clip); canvas.drawPath(transformedPath, paint); canvas.restore(); canvas.drawPath(transformedPath, borderPaint); }@Override public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); return true; }@Override public void onChange(Matrix matrix) { path.transform(matrix, transformedPath); invalidate(); }Bitmap blur(Context ctx, Bitmap src, float radius) { Bitmap bitmap = src.copy(src.getConfig(), true); RenderScript renderScript = RenderScript.create(ctx); Allocation blurInput = Allocation.createFromBitmap(renderScript, src); Allocation blurOutput = Allocation.createFromBitmap(renderScript, bitmap); ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript)); blur.setInput(blurInput); blur.setRadius(radius); blur.forEach(blurOutput); blurOutput.copyTo(bitmap); renderScript.destroy(); return bitmap; } }class MatrixGestureDetector { private static final String TAG ="MatrixGestureDetector"; interface OnMatrixChangeListener { void onChange(Matrix matrix); }private int ptpIdx = 0; private Matrix mTempMatrix = new Matrix(); private Matrix mMatrix; private OnMatrixChangeListener mListener; private float[] mSrc = https://www.songbingjia.com/android/new float[4]; private float[] mDst = new float[4]; private int mCount; public MatrixGestureDetector(Matrix matrix, MatrixGestureDetector.OnMatrixChangeListener listener) { if (matrix == null) throw new RuntimeException("Matrix cannot be null"); if (listener == null) throw new RuntimeException("OnMatrixChangeListener cannot be null"); mMatrix = matrix; mListener = listener; }public void onTouchEvent(MotionEvent event) { if (event.getPointerCount() > 2) { return; }int action = event.getActionMasked(); int index = event.getActionIndex(); switch (action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: int idx = index * 2; mSrc[idx] = event.getX(index); mSrc[idx + 1] = event.getY(index); mCount++; ptpIdx = 0; break; case MotionEvent.ACTION_MOVE: for (int i = 0; i < mCount; i++) { idx = ptpIdx + i * 2; mDst[idx] = event.getX(i); mDst[idx + 1] = event.getY(i); } mTempMatrix.setPolyToPoly(mSrc, ptpIdx, mDst, ptpIdx, mCount); mMatrix.postConcat(mTempMatrix); mListener.onChange(mMatrix); System.arraycopy(mDst, 0, mSrc, 0, mDst.length); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: if (event.getPointerId(index) == 0) ptpIdx = 2; mCount--; break; } } }

编辑:当使用Bitmaps而不是Paths时,代码会缩短几行:
class V extends View implements MatrixGestureDetector.OnMatrixChangeListener { Paint monoPaint = new Paint(); Paint srcInPaint = new Paint(); Bitmap mask, maskShadow, bitmap, blur; Matrix matrix = new Matrix(); Matrix maskMatrix = new Matrix(); MatrixGestureDetector detector; RectF clip = new RectF(); public V(Context context) { super(context); mask = BitmapFactory.decodeResource(context.getResources(), R.drawable.mask).extractAlpha(); maskShadow = BitmapFactory.decodeResource(context.getResources(), R.drawable.mask_shadow); bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.forest); blur = blur(context, bitmap, 8); ColorMatrix cm = new ColorMatrix(); cm.setSaturation(0.25f); monoPaint.setColorFilter(new ColorMatrixColorFilter(cm)); srcInPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); detector = new MatrixGestureDetector(maskMatrix, this); }@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { RectF src = https://www.songbingjia.com/android/new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); RectF dst = new RectF(0, 0, w, h); matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); matrix.mapRect(dst, src); src.set(0, 0, mask.getWidth(), mask.getHeight()); maskMatrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER); setupClip(); }private void setupClip() { clip.set(0, 0, mask.getWidth(), mask.getHeight()); maskMatrix.mapRect(clip); }@Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(blur, matrix, monoPaint); drawMask(canvas); }private void drawMask(Canvas canvas) { canvas.clipRect(clip); canvas.saveLayer(clip, null, 0); canvas.drawBitmap(mask, maskMatrix, null); canvas.drawB

    推荐阅读