如何修改位图网格样本以包含鱼眼效果?

发布于 2024-10-29 07:32:26 字数 4691 浏览 1 评论 0原文

我有一些 Android 附带的示例代码,它会扭曲位图图像(Bitmapmesh.java)。我想要在图像上放置一个圆圈,以产生鱼眼效果。我是 android 新手,尤其是图形新手,是否可以在 bitmapmesh 示例中创建这种效果?

我不知道从哪里开始,所以任何指示将不胜感激。任何人都可以给我所涉及内容的高级视图,例如我想首先在图像上放置一个圆圈。我已经将按钮放置在图像上,然后看起来像是浮动的,这是通过使用相对布局然后添加子按钮来完成的。我现在想做的事情有所不同,可能会涉及调用一些 onDraw 方法?我还有一个可以进行失真的算法,我只是不确定如何将其应用于图像。

下面是位图网格代码。谁能告诉我从哪里开始,即使只是先将圆圈放在图像上,然后我就可以解决实现效果的问题。

谢谢 mat

导入 java.io.BufferedInputStream; 导入java.io.DataInputStream; 导入java.io.File; 导入 java.io.FileInputStream; 导入 java.io.InputStream;

导入 android.content.Context; 导入 android.graphics.; 导入 android.os.Bundle; 导入 android.os.Environment; 导入 android.view.; 导入 android.util.FloatMath;

公共类 BitMapFishEye 扩展 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 File tempFile;
    private byte[] imageArray;

    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.beach);*/
        tempFile = new File(Environment.getExternalStorageDirectory().
                getAbsolutePath() + "/"+"image.jpg");

        imageArray = new byte[(int)tempFile.length()];

     try{

        InputStream is = new FileInputStream(tempFile);
            BufferedInputStream bis = new BufferedInputStream(is);
            DataInputStream dis = new DataInputStream(bis);


            int i = 0;

            while (dis.available() > 0) {
            imageArray[i] = dis.readByte();
            i++;
            }

            dis.close();

     } catch (Exception e) {

               e.printStackTrace();
            }


        BitmapFactory.Options bfo = new BitmapFactory.Options();
        bfo.inSampleSize = 5;
        mBitmap = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length, bfo);

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

}

I've some sample code that comes with Android that distorts a bitmap image(Bitmapmesh.java). I'm wanting a circle placed on my image that gives a fisheye effect. I'm new to android and especially graphics, is it possible to create this effect in the bitmapmesh sample?

I'm not sure where to start with this so any pointers would be appreciated. Can anyone give me a high level view of what's involved, eg i'd like to place a circle on the image firstly. i've placed buttons over images before that seem to float, this was done by using a relative layout then adding child buttons. what i'm tring to do now is different and will probably involve calling some onDraw method? i also have an algorithm that does the distortion, i'm just not sure how to apply this to the image.

Below is the bitmapmesh code. Can anyone talk me through where to start, even if it's just placing the circle on the image first, then i can tackle implementing the effect.

thanks mat

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import android.content.Context;
import android.graphics.;
import android.os.Bundle;
import android.os.Environment;
import android.view.
;
import android.util.FloatMath;

public class BitMapFishEye 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 File tempFile;
    private byte[] imageArray;

    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.beach);*/
        tempFile = new File(Environment.getExternalStorageDirectory().
                getAbsolutePath() + "/"+"image.jpg");

        imageArray = new byte[(int)tempFile.length()];

     try{

        InputStream is = new FileInputStream(tempFile);
            BufferedInputStream bis = new BufferedInputStream(is);
            DataInputStream dis = new DataInputStream(bis);


            int i = 0;

            while (dis.available() > 0) {
            imageArray[i] = dis.readByte();
            i++;
            }

            dis.close();

     } catch (Exception e) {

               e.printStackTrace();
            }


        BitmapFactory.Options bfo = new BitmapFactory.Options();
        bfo.inSampleSize = 5;
        mBitmap = BitmapFactory.decodeByteArray(imageArray, 0, imageArray.length, bfo);

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文