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.inSample开发者_如何学JAVASize = 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;
}
}
}
精彩评论