Android – efecto de deformación de imagen

En mi aplicación Android, quiero aplicar efecto de warp imagen proporcionado en la aplicación Photo Warp y Photo Deformer . Para eso utilicé BitmapMesh . El problema es que, no es el ahorro imagen deformada. Siempre que toco la imagen, refresco la imagen y no ahorro mi imagen warped previamente. Quiero ahorrar esa imagen siempre que el usuario realice la operación de la deformación. Aquí estoy publicando mi código. Aquí estoy utilizando "BitmapMesh" actividad para realizar el efecto warp en la imagen.

Por favor ayúdame a resolver este problema. Gracias.

Código:

BitmapMesh Actividad:

 import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.os.Bundle; import android.util.FloatMath; import android.view.MotionEvent; import android.view.View; public class BitmapMesh extends GraphicsActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private static final int WIDTH = 20; private static final int HEIGHT = 20; private static final int COUNT = (WIDTH + 1) * (HEIGHT + 1); private final Bitmap mBitmap; private final float[] mVerts = new float[COUNT * 2]; private final float[] mOrig = new float[COUNT * 2]; private final Matrix mMatrix = new Matrix(); private final Matrix mInverse = new Matrix(); private static void setXY(float[] array, int index, float x, float y) { array[index * 2 + 0] = x; array[index * 2 + 1] = y; } public SampleView(Context context) { super(context); setFocusable(true); mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image1); float w = mBitmap.getWidth(); float h = mBitmap.getHeight(); // construct our mesh int index = 0; for (int y = 0; y <= HEIGHT; y++) { float fy = h * y / HEIGHT; for (int x = 0; x <= WIDTH; x++) { float fx = w * x / WIDTH; setXY(mVerts, index, fx, fy); setXY(mOrig, index, fx, fy); index += 1; } } mMatrix.setTranslate(10, 10); mMatrix.invert(mInverse); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFCCCCCC); canvas.concat(mMatrix); canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0, null, 0, null); } private void warp(float cx, float cy) { final float K = 10000; float[] src = mOrig; float[] dst = mVerts; for (int i = 0; i < COUNT * 2; i += 2) { float x = src[i + 0]; float y = src[i + 1]; float dx = cx - x; float dy = cy - y; float dd = dx * dx + dy * dy; float d = FloatMath.sqrt(dd); float pull = K / (dd + 0.000001f); pull /= (d + 0.000001f); // android.util.Log.d("skia", "index " + i + " dist=" + d + // " pull=" + pull); if (pull >= 1) { dst[i + 0] = cx; dst[i + 1] = cy; } else { dst[i + 0] = x + dx * pull; dst[i + 1] = y + dy * pull; } } } private int mLastWarpX = -9999; // don't match a touch coordinate private int mLastWarpY; @Override public boolean onTouchEvent(MotionEvent event) { float[] pt = { event.getX(), event.getY() }; mInverse.mapPoints(pt); int x = (int) pt[0]; int y = (int) pt[1]; if (mLastWarpX != x || mLastWarpY != y) { mLastWarpX = x; mLastWarpY = y; warp(pt[0], pt[1]); invalidate(); } return true; } } } 

Gráficos Actividad:

 import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; class GraphicsActivity extends Activity { // set to true to test Picture private static final boolean TEST_PICTURE = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void setContentView(View view) { if (TEST_PICTURE) { ViewGroup vg = new PictureLayout(this); vg.addView(view); view = vg; } super.setContentView(view); } } 

PictureLayout.java

 import android.content.Context; import android.graphics.Canvas; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.view.ViewParent; class PictureLayout extends ViewGroup { private final Picture mPicture = new Picture(); public PictureLayout(Context context) { super(context); } public PictureLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void addView(View child) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child); } @Override public void addView(View child, int index) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index); } @Override public void addView(View child, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, params); } @Override public void addView(View child, int index, LayoutParams params) { if (getChildCount() > 1) { throw new IllegalStateException( "PictureLayout can host only one direct child"); } super.addView(child, index, params); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int count = getChildCount(); int maxHeight = 0; int maxWidth = 0; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { measureChild(child, widthMeasureSpec, heightMeasureSpec); } } maxWidth += getPaddingLeft() + getPaddingRight(); maxHeight += getPaddingTop() + getPaddingBottom(); Drawable drawable = getBackground(); if (drawable != null) { maxHeight = Math.max(maxHeight, drawable.getMinimumHeight()); maxWidth = Math.max(maxWidth, drawable.getMinimumWidth()); } setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec), resolveSize(maxHeight, heightMeasureSpec)); } private void drawPict(Canvas canvas, int x, int y, int w, int h, float sx, float sy) { canvas.save(); canvas.translate(x, y); canvas.clipRect(0, 0, w, h); canvas.scale(0.5f, 0.5f); canvas.scale(sx, sy, w, h); canvas.drawPicture(mPicture); canvas.restore(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight())); mPicture.endRecording(); int x = getWidth() / 2; int y = getHeight() / 2; if (false) { canvas.drawPicture(mPicture); } else { drawPict(canvas, 0, 0, x, y, 1, 1); drawPict(canvas, x, 0, x, y, -1, 1); drawPict(canvas, 0, y, x, y, 1, -1); drawPict(canvas, x, y, x, y, -1, -1); } } @Override public ViewParent invalidateChildInParent(int[] location, Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(0, 0, getWidth(), getHeight()); return getParent(); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = super.getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() != GONE) { final int childLeft = getPaddingLeft(); final int childTop = getPaddingTop(); child.layout(childLeft, childTop, childLeft + child.getMeasuredWidth(), childTop + child.getMeasuredHeight()); } } } } 

 //Little changes in this piece of code float[] dst; //Global public SampleView(Context context) { super(context); setFocusable(true); mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image1); float w = mBitmap.getWidth(); float h = mBitmap.getHeight(); // construct our mesh int index = 0; for (int y = 0; y <= HEIGHT; y++) { float fy = h * y / HEIGHT; for (int x = 0; x <= WIDTH; x++) { float fx = w * x / WIDTH; setXY(mVerts, index, fx, fy); setXY(mOrig, index, fx, fy); index += 1; dst=mVerts;//Assign dst here just once } } mMatrix.setTranslate(10, 10); mMatrix.invert(mInverse); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFCCCCCC); canvas.concat(mMatrix); canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, mVerts, 0, null, 0, null); } private void warp(float cx, float cy) { final float K = 10000; float[] src = dst; //now you are applying wrap effect on the last effected pixels for (int i = 0; i < COUNT * 2; i += 2) { float x = src[i + 0]; float y = src[i + 1]; float dx = cx - x; float dy = cy - y; float dd = dx * dx + dy * dy; float d = FloatMath.sqrt(dd); float pull = K / (dd + 0.000001f); pull /= (d + 0.000001f); // android.util.Log.d("skia", "index " + i + " dist=" + d + // " pull=" + pull); if (pull >= 1) { dst[i + 0] = cx; dst[i + 1] = cy; } else { dst[i + 0] = x + dx * pull; dst[i + 1] = y + dy * pull; } } } 
  • Disposición personalizada de Android - onDraw () nunca se llama
  • ¿Cómo funciona una propiedad Animate Layout de ViewGroups?
  • Cómo crear un botón que contiene varias vistas?
  • Problema en un grupo de vistas personalizado al actualizar ListViews
  • Android - Ocultar vistas
  • Android ViewGroup.setScaleX () hace que la vista se recorte
  • Activity.addContentView (Vista) == ViewGroup.addContentView (Ver)?
  • Cómo agregar un marcador pin en la vista de la imagen en android
  • Stackoverflow error en la vista
  • Android StackOverflowError en ViewGroup.resetResolvedTextDirection al agregar ListView a LinearLayout
  • Escala de diseño relativo personalizado?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.