任务内容:需要再主界面中显示截取圆形头像之后的结果,另外有一个界面用于拖动和放置所需要截取的图片。
现在我只完成了一个demo,边界限制等还没有实现,整理一下思路,先把这个demo放过来:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:layout_weight="4" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/image_to_show" android:layout_width="wrap_content" android:layout_height="wrap_content" /></FrameLayout> <Button android:id="@+id/start" android:textSize="25dp" android:text="没错就是这一张图片了!" android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/frame_layout" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:scaleType="matrix" android:id="@+id/imageView_ready_to_process" android:src="@drawable/face6" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:src="@drawable/crop" android:layout_width="match_parent" android:layout_height="wrap_content" /> </FrameLayout> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:layout_gravity="center" android:id="@+id/sure_to_crop" android:text="process" android:textSize="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/image_to_test" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>这里我用的是FrameLayout 便于连个文件的叠加;crop是我在drawbable中写的一个圆形的遮罩(可以这样理解吧。。)
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#00000000"/> <stroke android:width="3dp"/> <size android:width="400dp" android:height="400dp"/> </shape>在这里我设置了它的大小为400dp,其实这样写非常不恰当,我是测试过原图片的(face6)的大小为400dp左右才这么写的
package com.muxi.kolibreath.circleavatardemo; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.RectF; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { private Button start; private ImageView imageView_to_show; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView_to_show = (ImageView) findViewById(R.id.image_to_show); start = (Button) findViewById(R.id.start); frameLayout = (FrameLayout) findViewById(R.id.frame_layout); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this,EditActivity.class); startActivityForResult(intent,1); } }); } public Bitmap roundBitmap(Bitmap bitmap){ int width = bitmap.getWidth(); int height = bitmap.getHeight(); int radius = Math.min(width,height); Bitmap bitmap_for_canvas = Bitmap.createBitmap(radius,radius, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap_for_canvas); Paint paint = new Paint(); RectF rectF = new RectF(0,0,radius,radius); canvas.drawOval(rectF,paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); paint.setAntiAlias(true); //0,0表示距离bitmap左右图片的距离 canvas.drawBitmap(bitmap,0,0,paint); return bitmap_for_canvas; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode){ case 1: if(resultCode==RESULT_OK){ byte[] bytes = data.getByteArrayExtra("bitmap"); Log.d("size",bytes.length + ""); Bitmap bitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.length); imageView_to_show.setImageBitmap(roundBitmap(bitmap)); } break; } } }
package com.muxi.kolibreath.circleavatardemo; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.PointF; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.ImageView; import java.io.ByteArrayOutputStream; /** * Created by kolibreath on 2016/12/18. */ public class EditActivity extends AppCompatActivity implements View.OnClickListener{ private ImageView imageView_ready_to_process; private Button button; private Bitmap bitmap; private Bitmap image; private ImageView imageView_to_test; private static final String TAG1 = "height"; @Override protected void onCreate( Bundle savedInstanceState) { int imageId[] = new int[]{R.drawable.face6}; super.onCreate(savedInstanceState); setContentView(R.layout.process_pictures); button = (Button) findViewById(R.id.sure_to_crop); imageView_to_test= (ImageView) findViewById(R.id.image_to_test); imageView_ready_to_process = (ImageView) findViewById(R.id.imageView_ready_to_process); button.setOnClickListener(this); TouchListener touchListener = new TouchListener(); imageView_ready_to_process.setOnTouchListener(touchListener); imageView_ready_to_process.setImageResource(imageId[0]); } private final class TouchListener implements View.OnTouchListener{ private int mode = 0; private static final int DRAG=1; private static final int ZOOM=2; private PointF startPoint = new PointF(); private Matrix matrix = new Matrix(); private Matrix currentMatrix = new Matrix(); private float startDis; private PointF midPoint; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()&MotionEvent.ACTION_MASK){ case(MotionEvent.ACTION_DOWN): mode = DRAG; currentMatrix.set(imageView_ready_to_process.getImageMatrix()); startPoint.set(event.getX(),event.getY()); break; case (MotionEvent.ACTION_MOVE): if(mode == DRAG){ float dx = event.getX() - startPoint.x; float dy = event.getY() - startPoint.y; matrix.set(currentMatrix); matrix.postTranslate(dx,dy); }else if(mode == ZOOM){ float lastDis = distance(event); if(lastDis>10f) { double scale = lastDis / startDis; matrix.set(currentMatrix); matrix.postScale((float) scale, (float) scale, midPoint.x, midPoint.y); } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode =0; break; case MotionEvent.ACTION_POINTER_DOWN: mode = ZOOM; startDis = distance(event); if(startDis>10f){ midPoint = middle(event); currentMatrix.set(imageView_ready_to_process.getImageMatrix()); } break; } imageView_ready_to_process.setImageMatrix(matrix); return true; } } private float distance(MotionEvent event){ float dx = event.getX(1)- event.getX(0); float dy = event.getY(1)- event.getY(0); return (float)Math.sqrt(dx*dx +dy*dy); } private PointF middle(MotionEvent event){ float dx = (event.getX(1)- event.getX(0))/2; float dy = (event.getY(1)- event.getY(0))/2; return new PointF(dx,dy); } @Override public void onClick(View v) { Intent intent = new Intent(); image = BitmapFactory.decodeResource(this.getResources(),R.drawable.face6); bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.face6); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); //CompressFormat 可以指定解析图片的格式,后面的一个int参数表示解析的质量 //解析的图片如果质量太高就会报错 bitmap.compress(Bitmap.CompressFormat.JPEG,10,byteArrayOutputStream); byte[] bytes = byteArrayOutputStream.toByteArray(); intent.putExtra("bitmap",bytes); imageView_to_test.setImageBitmap(BitmapFactory.decodeByteArray(bytes,0,bytes.length)); setResult(RESULT_OK,intent); //不需要写startActivity() finish(); } }然后这个demo就完成了,接下来的完整版我写完之后再放过来。