2013-09-26 34 views
6

Android uygulamasında, Photo Warp ve Photo Deformer uygulamalarında görüntülenen görüntüyü warp efekti uygulamak istiyorum. Bunun için BitmapMesh kullanıyorum. Sorun şu ki, çarpık görüntüyü kaydetmiyor. Görüntüye her dokunduğumda, görüntüyü yeniler ve daha önce çizdiğim görüntüyü kaydetmez. Kullanıcı, çözgü işlemini gerçekleştirdiğinde bu resmi kaydetmek istiyorum. İşte kodumu gönderiyorum. Burada görüntüde çözgü efekti gerçekleştirmek için "BitmapMesh" aktivitesini kullanıyorum.Android - Görüntü Çözgü efekti

Lütfen bu sorunu çözmek için bana yardım edin. Teşekkürler.

Kodu:

BitmapMesh Etkinlik:

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

Grafik Etkinlik:

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

çözümü buldunuz mu? –

+0

no herhangi bir çözüm bulamadım.Ama bu efekti istiyorsanız o zaman android ile 'OpenCV' kullanmak zorunda kalabilirsiniz. Bunun hakkında fazla bir fikrim yok ama bu konuda dersler alacaksın. – zanky

+0

'OpenCv' dışında herhangi bir çözüm bulursanız, lütfen' OpenCV' yi android ile bütünleştirmek istemediğimi de bildirin. – zanky

cevap

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

    } 
İlgili konular