2013-09-26 8 views
6

मेरी एंड्रॉयड आवेदन में, मैं छवि warpPhoto Warp और Photo Deformer आवेदन में प्रदान की प्रभाव लागू करना चाहते हैं। इसके लिए मैंने BitmapMesh का उपयोग किया। समस्या यह है कि, यह विकृत छवि को नहीं बचा रहा है। जब भी मैं छवि को स्पर्श करता हूं, यह छवि को रीफ्रेश करता है और मेरी पिछली विकृत छवि को सहेजता नहीं है। जब भी उपयोगकर्ता वार्प ऑपरेशन करता है तो मैं उस छवि को सहेजना चाहता हूं। यहां मैं अपना कोड पोस्ट कर रहा हूं। यहां मैं छवि पर वार्प प्रभाव करने के लिए "बिटमैपमेश" गतिविधि का उपयोग कर रहा हूं।एंड्रॉयड - छवि वार्प प्रभाव

कृपया इस समस्या को हल करने में मेरी मदद करें। धन्यवाद।

कोड:

BitmapMesh गतिविधि:

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

ग्राफिक्स गतिविधि:

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

क्या आपको समाधान मिला है? –

+0

नहीं मुझे कोई समाधान नहीं मिला है। लेकिन अगर आप इस प्रभाव को चाहते हैं तो आपको एंड्रॉइड के साथ 'ओपनसीवी' का उपयोग करना पड़ सकता है। मुझे इसके बारे में ज्यादा जानकारी नहीं है लेकिन आपको उस पर ट्यूटोरियल मिलेगा। – zanky

+0

यदि आपको 'ओपनसीवी' के अलावा कोई समाधान मिलता है तो कृपया मुझे बताएं, क्योंकि मैं एंड्रॉइड के साथ 'ओपनसीवी' को एकीकृत नहीं करना चाहता हूं। – zanky

उत्तर

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

    } 
संबंधित मुद्दे