在我的
Android应用程序中,我想应用
Photo Warp和
Photo Deformer应用程序中提供的图像扭曲效果.为此,我使用了BitmapMesh.问题是,它不能保存扭曲的图像.每当我触摸图像时,它都会刷新图像并且不会保存我之前变形的图像.我想在用户执行扭曲操作时保存该图像.我在这里发布我的代码.这里我使用“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,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,null,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,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,w,h); canvas.scale(0.5f,0.5f); canvas.scale(sx,sy,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,x,y,1,1); drawPict(canvas,-1,-1); drawPict(canvas,-1); } } @Override public ViewParent invalidateChildInParent(int[] location,Rect dirty) { location[0] = getLeft(); location[1] = getTop(); dirty.set(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()); } } } }
解决方法
//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,fy); setXY(mOrig,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,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; } } }