Android中常用的选择图像,跟换图像等(图像放大缩小等)
16lz
2021-01-24
Android 一个图像选择和跟换图片的程序,选择图片可以进行放大缩小等
demo源码的下载地址:http://download.csdn.net/detail/dr_abandon/9906445
下面效果图:
1.点击进行图片选择
2.可以进行图片的放大或缩小
3.可以进行拍照等
MainActivity
就是一个图片进行选择跳转
public class MainActivity extends AppCompatActivity { public static final int REQUEST_IMAGE = 411; ImageView iv; //本地头像地址 String path; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //跳到选择图片页面 startActivityForResult(new Intent(getBaseContext(), SelectImageActivity.class), REQUEST_IMAGE); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_IMAGE && resultCode == RESULT_OK) { path = data.getStringExtra("path"); File file = new File(path); iv.setImageURI(Uri.fromFile(file)); } }}
SelectImageActivity选择照片页
//这里进行手机储存卡中照片的读取显示,存储,选择等一些操作public class SelectImageActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private static final int REQUEST_CAMERA = 102; public static final String IMAGE_PATH = Environment.getExternalStorageDirectory() + "/example"; TextView tv_cancel; TextView tv_title; TextView tv_finish; ScrollView sv_context; ScaleImageView siv_pic; ScrollGridView sgv_content; RelativeLayout rl_title; //GridView adapter 的数据源 List imageList = new ArrayList<>(); CameraAdapter adapter; String path = null; String name = ""; private List dirList = new ArrayList<>(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_select_image); tv_cancel = (TextView) findViewById(R.id.tv_cancel); tv_title = (TextView) findViewById(R.id.tv_title); tv_finish = (TextView) findViewById(R.id.tv_finish); sv_context = (ScrollView) findViewById(R.id.sv_context); siv_pic = (ScaleImageView) findViewById(R.id.siv_pic); sgv_content = (ScrollGridView) findViewById(R.id.sgv_content); rl_title = (RelativeLayout) findViewById(R.id.rl_title); tv_cancel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { finish(); } }); tv_title.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { showPopwindow(); } }); tv_finish.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { goBack(); } }); new File(IMAGE_PATH).mkdirs(); List files = FileUtils.getAllImageFile(); // imageList.addAll(files); Log.e("----","files.size()="+files.size()); MyApp.getInstance().setImgList(files); initView(); } private void goBack() { new Thread() { @Override public void run() { path = IMAGE_PATH + "/" + System.currentTimeMillis() + ".png"; siv_pic.getImagePath(path); setResult(RESULT_OK, getIntent().putExtra("path", path)); finish(); } }.start(); } private void showPopwindow() { tv_title.setSelected(true); ShowDirPopWindow popwindow = new ShowDirPopWindow(this, dirList, new ShowDirPopWindow.OnPopwindowItemClick() { @Override public void onClick(String dirName) { //需要开始修改dir if (dirName.equals("所有图片")) { for (ShowDirPopWindow.Dir dir : dirList) { dir.setCheck(false); } dirList.get(0).setCheck(true); imageList.clear(); imageList.addAll(MyApp.getInstance().getImgList()); tv_title.setText("所有图片"); } else { //不是第0个所有图片被选中 dirList.get(0).setCheck(false); for (int i = 1; i < dirList.size(); i++) { ShowDirPopWindow.Dir dir = dirList.get(i); //遍历判断 是否和用户选中的名称相同 if (dir.getFirstImage().getParent().equals(dirName)) { dir.setCheck(true); } else dir.setCheck(false); } //开始遍历本地文件 //C:/aaa.jpg c:/aaaa/ddd/bbb.jpg imageList.clear(); for (File file : MyApp.getInstance().getImgList()) { if (file.getAbsolutePath().contains(dirName)) { imageList.add(file); } } tv_title.setText(new File(dirName).getName()); } adapter.notifyDataSetChanged(); } }); popwindow.showAsDropDown(rl_title, 0, 0); popwindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { tv_title.setSelected(false); } }); } protected void initView() { //判断本地图片是否缓存成功 if (MyApp.getInstance().getImgList() == null) { Toast.makeText(getBaseContext(),"图片正在加载中,请稍后",Toast.LENGTH_SHORT).show(); finish(); } //第一次加载所有图片 imageList.addAll(MyApp.getInstance().getImgList()); adapter = new CameraAdapter(this, imageList); sgv_content.setAdapter(adapter); sgv_content.setOnItemClickListener(this); siv_pic.setImageBitmap(BitmapFactory.decodeFile(imageList.get(0).getAbsolutePath())); initDir(); } private void initDir() { //key == dir名称 //value = dir中有多少图片 HashMap sizeMap = new HashMap<>(); HashMap firstMap = new HashMap<>(); //第一次添加 dirList.add(new ShowDirPopWindow.Dir(imageList.get(0), "所有图片", imageList.size(), true)); // C:/aaa/bb.jpg; C:/aaa/sadf.jpg firstImage for (File file : imageList) { //拿 file在HashMap中的数量 Integer size = sizeMap.get(file.getParentFile().getAbsolutePath()); //null if (size == null) { sizeMap.put(file.getParentFile().getAbsolutePath(), 1); //图片 firstMap.put(file.getParentFile().getAbsolutePath(), file.getAbsolutePath()); } else { sizeMap.put(file.getParentFile().getAbsolutePath(), size + 1); } } Set set = sizeMap.keySet(); Iterator it = set.iterator(); while (it.hasNext()) { String key = it.next(); int size = sizeMap.get(key); String firstImage = firstMap.get(key); String name = new File(key).getName(); File firstFile = new File(firstImage); ShowDirPopWindow.Dir dir = new ShowDirPopWindow.Dir(firstFile, name, size, false); dirList.add(dir); } } @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { if (i != 0) { view.setSelected(true); siv_pic.setImageBitmap(BitmapFactory.decodeFile(imageList.get(i - 1).getAbsolutePath())); sv_context.fullScroll(View.FOCUS_UP); } else { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); name = System.currentTimeMillis() + ".jpg"; intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(IMAGE_PATH, name))); startActivityForResult(intent, REQUEST_CAMERA); } } /** * 得到所有的图片 */ static class FileUtils { public static final List getAllImageFile() { List list = new ArrayList<>(); getDirImage(Environment.getExternalStorageDirectory(), list); return list; } private static void getDirImage(File dir, List list) { File[] files = dir.listFiles(); if (files == null) return; for (File file : files) { if (file.isDirectory()) getDirImage(file, list); else { if (file.getName().endsWith(".png") || file.getName().endsWith(".jpg")) { list.add(file); } } } } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) { path = IMAGE_PATH + "/" + name; File file = new File(path); MyApp.getInstance().getImgList().add(file); siv_pic.setImageBitmap(BitmapFactory.decodeFile(path)); } }}
CameraAdapter获取手机图片显示的adapter
//第一个位置是给手机的照相机的public class CameraAdapter extends BaseAdapter { private int selectImage = -1; private final Context context; private final List list; public CameraAdapter(Context context, List list) { this.context = context; this.list = list; } @Override public int getCount() { return list == null ? 0 : list.size(); } @Override public File getItem(int i) { return list.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int position, View view, ViewGroup viewGroup) { ViewHolder holder; if (view == null) { view = View.inflate(context, R.layout.item_camera, null); holder = new ViewHolder(view); int width = context.getResources().getDisplayMetrics().widthPixels / 3; LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, width); holder.iv_image.setLayoutParams(params); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } if (position == 0) { holder.iv_image.setImageResource(R.mipmap.icon_camera_pick_ng); } else { File file = getItem(position - 1); holder.iv_image.setImageURI(Uri.fromFile(file)); if (position == selectImage) { holder.ll_image.setSelected(true); } } return view; } class ViewHolder { ImageView iv_image; LinearLayout ll_image; ViewHolder(View view) { iv_image = view.findViewById(R.id.iv_image); ll_image = view.findViewById(R.id.ll_image); } }}
ScaleImageView可以进行放大缩小的View
public class ScaleImageView extends ImageView { Bitmap bmp; Paint paint; public static final int NONE = 1; public static final int DRAG = 2; public static final int SCALE = 3; private int type = NONE; //最大缩放 //最小缩放 public static final float MIN = 1f; public static final float MAX = 3f; //拖拽点 PointF dragPoint; //缩放中心点 PointF centerPoint; //当前缩放的长度 float distance; Matrix matrix; //是否画线 boolean isDrawLine; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); isDrawLine = false; invalidate(); } }; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (isDrawLine) { for (int i = 1; i < 3; i++) { canvas.drawLine(0, getHeight() / 3 * i, getWidth(), getHeight() / 3 * i, paint); canvas.drawLine(getWidth() / 3 * i, 0, getWidth() / 3 * i, getHeight(), paint); } } } public ScaleImageView(Context context) { super(context); init(); } private void init() { //必须设置 setScaleType(MATRIX); matrix = new Matrix(); // 平移,旋转,缩放,倾斜 setImageMatrix(matrix); paint = new Paint(); paint.setDither(true); paint.setAntiAlias(true); paint.setColor(Color.WHITE); paint.setStrokeWidth(2); } public ScaleImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } @Override public void setImageBitmap(Bitmap bm) { setBackgroundColor(Color.rgb(0x31, 0x33, 0x35)); int sceen = getResources().getDisplayMetrics().widthPixels; //图片到底有多大 float width = bm.getWidth(); float height = bm.getHeight(); //如果图片的宽高比view小,那么需要放大 if (width < sceen || height < sceen) { float min = width < height ? width : height; float rate = sceen / min; bmp = ThumbnailUtils.extractThumbnail(bm, (int) (width * rate), (int) (height * rate)); if (bm != null) bm.recycle(); } super.setImageBitmap(bmp); matrix = new Matrix(); setImageMatrix(matrix); } //在sd卡中的名称 public String getImagePath(String name) { //在子线程中操作 Bitmap bitmap = Bitmap.createBitmap(getWidth(), getWidth(), Bitmap.Config.ARGB_8888); //吧屏幕上的绘制进去 Canvas canvas = new Canvas(bitmap); canvas.drawBitmap(bmp, matrix, null); canvas.save(); FileOutputStream fos = null; try { fos = new FileOutputStream(name); } catch (FileNotFoundException e) { e.printStackTrace(); } bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); try { fos.close(); } catch (IOException e) { e.printStackTrace(); } return name; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, widthMeasureSpec); } @Override public boolean onTouchEvent(MotionEvent event) { isDrawLine = true; if (handler.hasMessages(1)) handler.removeMessages(1); handler.sendEmptyMessageDelayed(1, 2000); PointF pointf = new PointF(event.getX(), event.getY()); //多指运算 switch (event.getAction() & event.getActionMasked()) { case MotionEvent.ACTION_DOWN: //点上去 就显示出来 type = DRAG; dragPoint = new PointF(event.getX(), event.getY()); break; case MotionEvent.ACTION_POINTER_DOWN: type = SCALE; float x1 = event.getX(); float x2 = event.getX(1); float y1 = event.getY(); float y2 = event.getY(1); centerPoint = new PointF((x1 + x2) / 2, (y1 + y2) / 2); distance = getDistance(event); break; case MotionEvent.ACTION_POINTER_UP: //缩放复位 scaleReset(); break; case MotionEvent.ACTION_UP: //拖拽复位 dragReset(); type = NONE; break; case MotionEvent.ACTION_MOVE: //根据状态来判断是缩放还是拖拽 if (type == DRAG) { //当前的位置,移动的距离 matrix.postTranslate(pointf.x - dragPoint.x, pointf.y - dragPoint.y); dragPoint = new PointF(event.getX(), event.getY()); } else if (type == SCALE) { float rate = getDistance(event) / distance; matrix.postScale(rate, rate, centerPoint.x, centerPoint.y); } break; } setImageMatrix(matrix); invalidate(); return true; } private void scaleReset() { //matrix 9个值 float[] value = new float[9]; matrix.getValues(value); if (value[0] < MIN) matrix.postScale(MIN, MIN, centerPoint.x , centerPoint.y); else if (value[0] > MAX) matrix.postScale(MAX, MAX, centerPoint.x, centerPoint.y); } private void dragReset() { //需要获取图片在哪里 RectF rectf = new RectF(0, 0, bmp.getWidth(), bmp.getHeight()); matrix.mapRect(rectf); Log.e("TAG", "矩形的上" + rectf.top + " 矩形的下" + rectf.bottom + " 矩形的右" + rectf.right + " 矩形的左" + rectf.left); Log.e("TAG", "view的高度" + getHeight() + " view的宽度" + getWidth()); //水平方向 float x = 0, y = 0; if (rectf.top > 0) { y = 0 - rectf.top; } else if (rectf.bottom < getHeight()) { y = getHeight() - rectf.bottom;//正 右和下 } if (rectf.left > 0) { x = 0 - rectf.left; } else if (rectf.right < getWidth()) { x = getWidth() - rectf.right; } matrix.postTranslate(x, y); } @Override public void setImageResource(int resId) { super.setImageResource(resId); setImageBitmap(BitmapFactory.decodeResource(getResources(), resId)); } public float getDistance(MotionEvent event) { float x1 = event.getX(); float x2 = event.getX(1); float y1 = event.getY(); float y2 = event.getY(1); return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2); } //重写事件处理 @Override public boolean dispatchTouchEvent(MotionEvent event) { //当父类与自己同时具有同一方向的滑动,会导致子控件无法获取焦点 //ViewPager嵌套ViewPager //请求父窗体不要拦截事件 getParent().requestDisallowInterceptTouchEvent(true); return super.dispatchTouchEvent(event); }}
下面是选择图片的xml布局
<?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"> <RelativeLayout android:id="@+id/rl_title" android:layout_width="match_parent" android:layout_height="50dp" android:background="@color/image_title"> <TextView android:id="@+id/tv_cancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:text="取消" android:textColor="@android:color/darker_gray" /> <TextView android:id="@+id/tv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:drawablePadding="5dp" android:drawableRight="@drawable/title_arrow_selector" android:text="所有图片" android:textColor="@android:color/darker_gray" /> <TextView android:id="@+id/tv_finish" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:text="完成" android:textColor="@color/image_finish" /> RelativeLayout> <ScrollView android:id="@+id/sv_context" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.example.administrator.myapplication.ScaleImageView android:id="@+id/siv_pic" android:layout_width="match_parent" android:layout_height="wrap_content" /> <com.example.administrator.myapplication.ScrollGridView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/sgv_content" android:numColumns="3" /> LinearLayout> ScrollView>LinearLayout>
部分代码没有上传,感兴趣的童靴可以下载整个demo:http://download.csdn.net/detail/dr_abandon/9906445
如有不足欢迎探讨,至无所畏惧的你。
更多相关文章
- Android应用屏幕适应问题的解决
- Android异步加载图片中UI是否被阻塞的测试
- Android(安卓)App自适应draw9patch不失真背景.9.png详解
- Android中画图
- Android之自定义View:圆形ImageView实现可暂停的旋转动画效果
- Android——Matrix类
- Android(安卓)滑动效果进阶篇(六)—— 倒影效果
- Android中播放视频的三种方式
- android相册选择图片的编码实现