Android的:如何变形的图像? [英] Android: how to warp images?

查看:176
本文介绍了Android的:如何变形的图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要变形这样的图片:

补充2013年8月4日的:我用这个code,但它不能正常工作:

 私有静态最终诠释WIDTH = 20;
    私有静态最终诠释HEIGHT = 20;
    私有静态最终诠释COUNT =(宽+ 1)*(高+ 1);

    私人最终位图mBitmap;
    私人最终浮动[] mVerts =新的浮动[COUNT * 2];
    私人最终浮动[] mOrig =新的浮动[COUNT * 2];

    私人最终矩阵mMatrix =新的Matrix();
    私人最终矩阵MINVERSE =新的Matrix();

    私有静态无效setXY(浮动[]数组,INT指数,浮动的x,浮动Y){
        数组[索引* 2 + 0] = X;
        数组[索引* 2 + 1] = Y;
    }

    公共SampleView(上下文的背景下){
        超(上下文);
        setFocusable(真正的);

        mBitmap = BitmapFactory.de codeResource(getResources()
                                                 R.drawable.ic_launcher);

        浮瓦特= mBitmap.getWidth();
        浮动H = mBitmap.getHeight();
        //构造我们的目
        INT索引= 0;
        对于(INT Y = 0; Y< =身高; Y ++){
            浮财年= H * Y /高度;
            为(中间体X = 0 X  - 其中=宽度; X ++){
                浮FX = W * X /宽;
                setXY(mVerts,指数,外汇,风云);
                setXY(mOrig,指数,外汇,风云);
                指数+ = 1;
            }
        }

        mMatrix.setTranslate(10,10);
        mMatrix.invert(MINVERSE);
    }

    @覆盖保护无效的OnDraw(帆布油画){
        canvas.drawColor(0xFFCCCCCC);

        canvas.concat(mMatrix);
        canvas.drawBitmapMesh(mBitmap,宽度,高度,mVerts,0,
                              NULL,0,NULL);
    }

    私人无效经线(浮点CX,浮CY){
        最终浮动K = 10000;
        浮动[] SRC = mOrig;
        浮动[] DST = mVerts;
        的for(int i = 0; I< COUNT * 2; I + = 2){
            浮X = SRC [I + 0];
            浮动Y = SRC [I + 1];
            浮DX = CX  -  X;
            浮DY = CY  - ÿ;
            浮DD = DX * DX + DY * DY;
            浮D = FloatMath.sqrt(DD);
            浮拉= K /(DD + 0.000001f);

            拉/ =(D + 0.000001f);
         // android.util.Log.d(Skia的指数+ I +DIST =+ D +拉=+拉);

            如果(拉> = 1){
                DST [I + 0] = CX;
                DST [I + 1] = CY;
            } 其他 {
                DST [1 + 0] = X + DX *拉;
                DST [I + 1] = Y + DY *拉;
            }
        }
    }

    私人诠释mLastWarpX = -9999; //不匹配触摸坐标
    私人诠释mLastWarpY;

    @覆盖公共布尔的onTouchEvent(MotionEvent事件){
        浮动[] PT = {event.getX(),event.getY()};
        mInverse.mapPoints(PT);

        INT X =(int)的角[0];
        INT Y =(int)的角[1];
        如果(mLastWarpX!= X || mLastWarpY!= Y){
            mLastWarpX = X;
            mLastWarpY = Y;
            经纱(磅[0],角[1]);
            无效();
        }
        返回true;
    }
 

解决方案

有一个编码比你自己更容易的方法。请参见 TransitionDrawable

  

LayerDrawables的一个扩展,旨在之间交叉衰减   在第一和第二层。要开始转型,调用   startTransition(INT)。要显示只是第一层,呼叫   resetTransition()。
  它可以在与一个XML文件中定义   <转型>元件。在过渡的每个绘制对象是在限定   嵌套<项目>

您可以找到行的 这里 是:

 < XML版本=1.0编码=UTF-8&GT?;
<过渡的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android>
  <项目机器人:可绘制=@可绘制/ first_image/>
  <项目机器人:可绘制=@可绘制/ second_image/>
< /转换>
 

和code

 最后ImageView的形象=(ImageView的)findViewById(R.id.image);
最后切换按钮按钮=(切换按钮)findViewById(R.id.button);
button.setOnClickListener(新OnClickListener(){
  @覆盖
  公共无效的onClick(最终查看V){
    TransitionDrawable绘制=(TransitionDrawable)image.getDrawable();
    如果(button.isChecked()){
      drawable.startTransition(500);
    } 其他 {
      drawable.reverseTransition(500);
    }
  }
});
 

I want to warp images like this:

Added 08-04-2013: I used this code but it's not working properly:

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

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

解决方案

There is a much easier way than coding you own. See TransitionDrawable

An extension of LayerDrawables that is intended to cross-fade between the first and second layer. To start the transition, call startTransition(int). To display just the first layer, call resetTransition().
It can be defined in an XML file with the <transition> element. Each Drawable in the transition is defined in a nested <item>

You can find many examples on line, here is one:

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:drawable="@drawable/first_image" />
  <item android:drawable="@drawable/second_image" />
</transition>

and the code

final ImageView image = (ImageView) findViewById(R.id.image);
final ToggleButton button = (ToggleButton) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(final View v) {
    TransitionDrawable drawable = (TransitionDrawable) image.getDrawable();
    if (button.isChecked()) {
      drawable.startTransition(500);
    } else {
      drawable.reverseTransition(500);
    }
  }
}); 

这篇关于Android的:如何变形的图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆