2017-06-22 44 views
0

我正在开发面部应用,如“老化的摊位”。我已经成功检测到面部并在其上施加了皱纹。 现在我想扭曲的脸像如下面的例子面部扭曲技术使其老化

Original Face

Required warping result

任何一个可以帮助我解决这个问题,通过引导我,我应该使用哪种技术,或者任何的源代码翘曲像这样的图像。

我尝试使用下面的代码来解决它。 但它没有给出所需的结果。因此,任何一个请编辑得到需要的结果或任何其他技术....

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Paint; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.Window; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 

public class MainActivity extends Activity { 

    //////////////////////////////////////////////////////// 
    ImageView img; 
    Bitmap face; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.activity_main); 

     LinearLayout ll01 = (LinearLayout) findViewById(R.id.linearLayout1); 

     SampleView sv = new SampleView(this); 
     ll01.addView(sv); 
    } 

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

    private static class SampleView extends View { 
     static int WIDTH = 8; // sections 
     static int HEIGHT = 8; 
     static int COUNT = (WIDTH + 1) * (HEIGHT + 1); // total verts count 

     Bitmap mBitmap; // declaring a bitmap 
     float[] matrixVertsMoved = new float[COUNT * 2]; // declaring an array with double amount of vert count, one for x and one for y 
     float[] matrixOriganal = new float[COUNT * 2]; 

     float clickX; 
     float clickY; 

     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.w); 


      // construct our mesh 
      int index = 0; 
      for (int y = 0; y <= HEIGHT; y++) { 
       float fy = mBitmap.getHeight() * y/HEIGHT; 

       for (int x = 0; x <= WIDTH; x++) { 
        float fx = mBitmap.getWidth() * x/WIDTH; 
        setXY(matrixVertsMoved, index, fx, fy); 
        setXY(matrixOriganal, index, fx, fy); 
        index += 1; 
       } 

      } 

     } 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

     @Override 
     protected void onDraw(Canvas canvas) { 


      canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT, matrixVertsMoved, 0, null, 0, null); 

      Paint p1 = new Paint(); 
      p1.setColor(0x660000FF); 

      Paint p2 = new Paint(); 
      p2.setColor(0x99FF0000); 

      Paint p3 = new Paint(); 
      p3.setColor(0xFFFFFB00); 

      for (int i = 0; i < COUNT * 2; i += 2) { 
       float x = matrixOriganal[i + 0]; 
       float y = matrixOriganal[i + 1]; 
       canvas.drawCircle(x, y, 4, p1); 

       float x1 = matrixOriganal[i + 0]; 
       float y1 = matrixOriganal[i + 1]; 
       float x2 = matrixVertsMoved[i + 0]; 
       float y2 = matrixVertsMoved[i + 1]; 
       canvas.drawLine(x1, y1, x2, y2, p1); 
      } 

      for (int i = 0; i < COUNT * 2; i += 2) { 
       float x = matrixVertsMoved[i + 0]; 
       float y = matrixVertsMoved[i + 1]; 
       canvas.drawCircle(x, y, 4, p2); 
      } 

      canvas.drawCircle(clickX, clickY, 6, p3); 


     } 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

     private void smudge() { 


      for (int i = 0; i < COUNT * 2; i += 2) { 

       float xOriginal = matrixOriganal[i + 0]; 
       float yOriginal = matrixOriganal[i + 1]; 

       float dist_click_to_origin_x = clickX - xOriginal; // distance from current vertex in the original matrix to the place clicked. 
       float dist_click_to_origin_y = clickY - yOriginal; 

       float kv_kat = dist_click_to_origin_x * dist_click_to_origin_x + dist_click_to_origin_y * dist_click_to_origin_y; 

       float pull = (1000000/kv_kat/(float) Math.sqrt(kv_kat)); 

       if (pull >= 1) { 
        matrixVertsMoved[i + 0] = clickX; 
        matrixVertsMoved[i + 1] = clickY; 
       } else { 
        matrixVertsMoved[i + 0] = xOriginal + dist_click_to_origin_x * pull; 
        matrixVertsMoved[i + 1] = yOriginal + dist_click_to_origin_y * pull; 
       } 

      } 


     } 


//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

     @Override 
     public boolean onTouchEvent(MotionEvent event) { 

      clickX = event.getX(); 
      clickY = event.getY(); 
      smudge(); // change the matrix. 
      invalidate(); // calls a redraw on the canvas. 

      return true; 
     } 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

    } 
} 
+0

https://stackoverflow.com/help/how-to-ask:您应该检查这篇文章。 Stackoverflow不会提供代码,但可以帮助您解决代码中您遇到的错误。 – Esteban

回答

0
public Bitmap ExtendBitmap(Bitmap normalImage){ 


    int w = normalImage.getWidth(); 
    int h = normalImage.getHeight(); 
    int thirdWidht = w/3; 

//create a new blank image 
    Bitmap stretchImage = Bitmap.createBitmap(w + thirdWidht, h, Bitmap.Config.ARGB_8888); 

    Canvas c = new Canvas(stretchImage); 

//draw left bit 
    c.drawBitmap(normalImage, new Rect(0,0,thirdWidht,h), new Rect(0,0,thirdWidht,h), null); 

//draw stretched middle bit 
    c.drawBitmap(normalImage, new Rect(thirdWidht,0,thirdWidht * 2, h), new Rect(thirdWidht,0,thirdWidht * 3,h), null); 

//draw right bit 
    c.drawBitmap(normalImage, new Rect(thirdWidht * 2,0,w,h), new Rect(thirdWidht * 3,0,w + thirdWidht,h), null); 

    return stretchImage; 
}