2013-09-26 22 views
6

Nella mia applicazione Android, voglio applicare l'effetto immagine warp fornito nell'applicazione Photo Warp e Photo Deformer. Per quello ho usato BitmapMesh. Il problema è che non sta salvando l'immagine deformata. Ogni volta che tocco un'immagine, aggiorna l'immagine e non salva la mia immagine precedentemente deformata. Voglio salvare quell'immagine ogni volta che l'utente esegue un'operazione di deformazione. Qui sto postando il mio codice. Qui sto usando l'attività "BitmapMesh" per eseguire l'effetto di distorsione sull'immagine.Android - Effetto Effetto immagine

Please help me per risolvere questo problema. Grazie.

Codice:

BitmapMesh attività:

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; 
     } 
    } 
} 

Grafica attività:

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()); 

      } 
     } 
    } 
} 
+0

hai trovato la soluzione? –

+0

no non ho trovato alcuna soluzione. Ma se vuoi questo effetto, potresti dover usare 'OpenCV' con Android. Non ne ho idea, ma su questo avrai tutorial. – zanky

+0

Se trovi una soluzione diversa da 'OpenCv', per favore fammi sapere, dato che non voglio integrare' OpenCV' con Android. – zanky

risposta

8
//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; 
      } 
     } 

    }