- 浏览: 14267 次
- 性别:
- 来自: 广州
最近访客 更多访客>>
文章分类
最新评论
-
enjoylrx:
你好,可以发工程文件或者贴上string.xml可以吗我的em ...
图片缩放、平移、剪切
盯了两天代码才实现的功能我不得不把他写上博客,共享!主要是实现从SD卡文件夹中读取一个图片,然后实现缩小放大,平移、剪切功能!直接上代码.
package demo.com; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.util.DisplayMetrics; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.Window; import android.view.WindowManager; import android.widget.EditText; import demo.utils.PictureView; public class PictureDispose extends Activity{ private PictureView pictureView = null; //图片路径 public static String photo_path = null; //旋转缩放的变量 float angle = 0.0f; float scale = 1.0f; //图片平移的xy坐标 int down_x = 0; int down_y = 0; int move_x = 0; int move_y = 0; int up_x = 0; int up_y = 0; //屏幕宽与高 public static int screen_width; public static int screen_height; //第一个menu菜单选项 protected static final int MENU_CUT = Menu.FIRST; //剪切标志 public static boolean cut = false; public static boolean cut_start = false; //剪切图片的名字 public static String cut_name = null; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); //无title requestWindowFeature(Window.FEATURE_NO_TITLE); //全屏 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getPhotoPath(); screenSize(); this.pictureView = new PictureView(this, photo_path, screen_width, screen_height); cut = false; cut_start = false; setContentView(pictureView); scale = pictureView.getScale(); } public void getPhotoPath(){ Intent intent = getIntent(); Bundle b = intent.getExtras(); String photoURL = b.getString("photoURL"); photo_path = photoURL; } //按照屏幕大小缩放图片 public void screenSize(){ DisplayMetrics displayMetric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(displayMetric); screen_height = displayMetric.heightPixels; screen_width = displayMetric.widthPixels; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if(!cut_start){ //向左旋转 if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT){ angle++; pictureView.setAngle(angle); } //向右旋转 if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){ angle--; pictureView.setAngle(angle); } //放大 if(keyCode == KeyEvent.KEYCODE_DPAD_UP){ if(scale < 2.9f) scale += 0.1f; else scale = 3.0f; System.out.println(scale); pictureView.setScale(scale); } //缩小 if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN){ if(scale > 0.2f) scale -= 0.1f; else scale = 0.1f; System.out.println(scale); pictureView.setScale(scale); } //返回键 if(keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() ==0){ if(cut){ cut = false; cut_start = false; }else{ this.finish(); } return true; } } return super.onKeyDown(keyCode, event); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub int action = event.getAction(); //如果是剪切的话就执行下面代码 if(cut){ int change_x = (int)event.getX(); int change_y = (int)event.getY(); if((change_x > pictureView.getleft()-25)//如果触点选中了左边框 && change_x < pictureView.getleft()+25 && (change_y > pictureView.gettop()) && (change_y < pictureView.getbottom())){ pictureView.setLeft(change_x); }else if((change_x > pictureView.getright()-25)//如果触点选中了右边框 && (change_x < pictureView.getright()+25) && (change_y > pictureView.gettop()) && (change_y < pictureView.getbottom())){ pictureView.setRight(change_x); }else if((change_y > pictureView.gettop()-25)//如果触点选中了上边框 && (change_y < pictureView.gettop()+25) && (change_x > pictureView.getleft()) && (change_x < pictureView.getright())){ pictureView.setTop(change_y); }else if((change_y > pictureView.getbottom()-25)//如果触点选中了下边框 && (change_y < pictureView.getbottom()+25) && (change_x > pictureView.getleft()) && (change_x < pictureView.getright())){ pictureView.setBottom(change_y); }else if((change_x < 88) && (change_y > (screen_height-35))){ //显示输入对话框 setDialog(); //取消剪切框 cut = false; cut_start = false; }else if((change_x > (screen_width-88)) && (change_y > (screen_height-35))){ //取消剪切框 cut = false; cut_start = false; }else if(!cut_start){ switch(action){ case MotionEvent.ACTION_DOWN: down_x = (int)event.getX(); down_y = (int)event.getY(); break; case MotionEvent.ACTION_MOVE: move_x = (int)event.getX(); move_y = (int)event.getY(); pictureView.setX(move_x-down_x+up_x); pictureView.setY(move_y-down_y+up_y); break; case MotionEvent.ACTION_UP: up_x = pictureView.getX(); up_y = pictureView.getY(); break; } } }else if(!cut_start){ switch(action){ case MotionEvent.ACTION_DOWN: down_x = (int)event.getX(); down_y = (int)event.getY(); break; case MotionEvent.ACTION_MOVE: move_x = (int)event.getX(); move_y = (int)event.getY(); pictureView.setX(move_x-down_x+up_x); pictureView.setY(move_y-down_y+up_y); break; case MotionEvent.ACTION_UP: up_x = pictureView.getX(); up_y = pictureView.getY(); break; } } return super.onTouchEvent(event); } //弹出对话框函数 public void setDialog(){ final EditText edit = new EditText(this); //弹出输入框,接收输入文件名 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.cuttitle) .setIcon(android.R.drawable.ic_dialog_info).setView( edit); builder.setPositiveButton(R.string.ok, new DialogInterface .OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub cut_name = edit.getText().toString(); dialog.dismiss(); cut = false; cut_start = true; } }).setNegativeButton(R.string.cancel, new DialogInterface .OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub cut = true; cut_start = false; dialog.dismiss(); } }).show(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // TODO Auto-generated method stub menu.add(0, MENU_CUT, 0, R.string.cut); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub switch(item.getItemId()){ case MENU_CUT: cut = true; cut_start = false; break; } return super.onOptionsItemSelected(item); } public int getScreen_width() { return screen_width; } public void setScreen_width(int screen_width) { PictureDispose.screen_width = screen_width; } public int getScreen_height() { return screen_height; } public void setScreen_height(int screen_height) { PictureDispose.screen_height = screen_height; } public static String getCut_name() { return cut_name; } public static void setCut_name(String cut_name) { PictureDispose.cut_name = cut_name; } }
package demo.utils; import java.io.File; import java.io.IOException; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.Rect; import android.view.View; import demo.com.PictureDispose; import demo.com.R; public class PictureView extends View implements Runnable{ //位图 Bitmap bm = null; //Matrix对象 private Matrix matrix = new Matrix(); //图像平移的xy坐标 private int x, y; //图像缩放,旋转 private float scale = 1.0f; private float angle = 0.0f; //图片的宽和高 private int w, h; //设置去除图像锯齿标志 private static PaintFlagsDrawFilter pdf = null; //绘制矩形的paint Paint paint = null; PictureDispose pictureDispose = new PictureDispose(); //矩形的边框大小 private int left = 0; private int right = 0; private int top = 0; private int bottom = 0; //剪切图片保存和放弃按钮 Bitmap abandon = null; Bitmap save = null; //缩放、剪切等临时用到图片 Bitmap bm2 = null; //文件处理类对象 FileUtils fileUtils = new FileUtils(); public PictureView(Context context, String path, int screenwidth, int screenheight) { super(context); // TODO Auto-generated constructor stub paint = new Paint(); //获得位图 bm = BitmapFactory.decodeFile(path); w = bm.getWidth(); h = bm.getHeight(); //如果高太高,按照图片高与屏幕高的比例缩小 float scaleWidth = ((float)screenheight)/h; float scaleHeight = ((float)screenwidth)/w; scale = Math.min(scaleWidth, scaleHeight); //设置矩形的初始化大小 left = screenwidth/3; top = screenheight/3; right = 2*screenwidth/3; bottom = 2*screenheight/3; new Thread(this).start(); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); //重置Matrixs matrix.reset(); //旋转图片 matrix.postRotate(angle); //缩放图片 matrix.postScale(scale, scale); //根据原始图片和matrix创建新视图 bm2 = Bitmap.createBitmap(bm, 0, 0, w, h, matrix, true); //绘制新视图 PictureView.drawImage(canvas, bm2, x, y); if(PictureDispose.cut){ paint.setAntiAlias(true); //设置颜色 paint.setARGB(255, 255, 0, 0); //设置透明值 paint.setAlpha(200); //设置矩形为空心 paint.setStyle(Paint.Style.STROKE); //设置空心外框大小 paint.setStrokeWidth(3); //矩形 Rect rect = new Rect(left, top, right, bottom); canvas.drawRect(rect, paint); //获取剪切保存,舍弃两个图片按钮 Resources res = getResources(); save = BitmapFactory.decodeResource(res, R.drawable.save); abandon = BitmapFactory.decodeResource(res, R.drawable.abandon); canvas.drawBitmap(save, 0, pictureDispose.getScreen_height()-35, null); canvas.drawBitmap(abandon, pictureDispose.getScreen_width()-88, pictureDispose.getScreen_height()-35, null); } //开始剪切图片 if(PictureDispose.cut_start){ //真正剪切框的大小为 int left_cut = left; int right_cut = right; int top_cut = top; int bottom_cut = bottom; //判断剪切框是否越界 if(left < x){ left_cut = x; } if(right > (x+bm2.getWidth())){ right_cut = x+bm2.getWidth(); } if(top < y){ top_cut = y; } if(bottom > (y+bm2.getHeight())){ bottom_cut = y+bm2.getHeight(); } System.out.println(x); System.out.println(y); System.out.println((bm2.getWidth())); System.out.println((bm2.getHeight())); System.out.println(left); System.out.println(top); System.out.println(right); System.out.println(bottom); System.out.println(left_cut); System.out.println(top_cut); System.out.println(right_cut-left_cut); System.out.println(bottom_cut-top_cut); int cut_width = right_cut-left_cut; int cut_height = bottom_cut-top_cut; Matrix m = new Matrix(); m.postTranslate(0, 0); Bitmap cuted_bitmap = Bitmap.createBitmap(bm2, left_cut-x, top_cut-y, cut_width, cut_height); //选择剪切区域 //Canvas c = new Canvas(); // //c.drawBitmap(bm2, left_cut, top_cut, null); //c.clipRect(left_cut, top_cut, right_cut, bottom_cut); //c.save(); // //System.out.println("1254"); Paint mPaint = new Paint(); mPaint.setColor(Color.BLACK); mPaint.setAntiAlias(true); canvas.drawRect(0, 0, PictureDispose.screen_width, PictureDispose.screen_height, mPaint); //在剪切的地方画图 canvas.drawBitmap(cuted_bitmap, left, top, null); //c.restore(); } } public static void drawImage(Canvas canvas, Bitmap bitmap, int x, int y){ //消除图片锯齿 pdf = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG); //消除锯齿 canvas.setDrawFilter(pdf); //绘制图像 canvas.drawBitmap(bitmap, x, y, null); } @Override public void run() { // TODO Auto-generated method stub while(!Thread.currentThread().isInterrupted()){ try{ Thread.sleep(100); }catch(InterruptedException e){ Thread.currentThread().interrupt(); } //使用postInvaate在线程直接更新界面 postInvalidate(); } } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public float getScale() { return scale; } public void setScale(float scale) { this.scale = scale; } public float getAngle() { return angle; } public void setAngle(float angle) { this.angle = angle; } public void setW(int w) { this.w = w; } public void setH(int h) { this.h = h; } public int getW() { return w; } public int getH() { return h; } public int getleft() { return left; } public void setLeft(int left) { this.left = left; } public int getright() { return right; } public void setRight(int right) { this.right = right; } public int gettop() { return top; } public void setTop(int top) { this.top = top; } public int getbottom() { return bottom; } public void setBottom(int bottom) { this.bottom = bottom; } }
相关推荐
此demo是模仿微信的上传头像可以自定义的对图片进行缩放,平移后剪切,也解决了三星的剪切图片时旋转问题,里面有设置图片旋转的相关代码,适合很多机型。
此资源根据模仿微信自定义裁剪图片的,实现了拍照上传裁剪和选择相册裁剪在三星、华为、小米、魅族手机,解决了三星手机上面的旋转问题。由于实现此功能浪费了我大半天时间,就在这里讨了2积分的赏!
1. 像素级:HSV增强、旋转、平移、缩放、剪切、透视、翻转等 2. 图片级:MixUp、Cutout、CutMix、Mosaic、Copy-Paste等 3. 基本图片处理方法:将图像的最长边缩放到640,短边填充到640等方法。 可供使用者完成开发...
该图片裁剪器基于gl-react-native 安装 npm i -S react-native-image-cropper 要么 yarn add react-native-image-cropper 要求 gl-react您需要安装gl-react。 npm i -S gl-react gl-react-native您需要安装gl-...
实现了图片经过平移,缩放,旋转手势后的完美剪切
一个微信小程序demo,用户可以上传一张图片,在canvas画布上展示,然后可以平移、单指旋转、双指缩放图片,最后将canvas区域内的图片内容保存到本地相册。采用了微信开发者文档的最新api,能够兼容大多数的场景,并...
【实例简介】 在WPF中使用opencvsharp操作图像,实现加载、翻转、旋转、缩放、平移、剪切、保存等操作。
Bitmap相信对各位Android开发者们来说都不陌生,用它可以获取图片信息,进行图片剪切、平移、旋转、缩放等操作,并可以指定格式保存图片文件。本文将对它的一些常见操作进行总结,下面话不多说了,来一起看看详细的...
qtransformtracker类能够动态的平移和缩放,还支持动态的旋转(需按下Ctrl键),按比例缩放,剪切变换,限制水平和垂直移动等。附demo,在VS2005环境下编译通过,能正常运行。
数据扩充涉及对现有训练数据添加随机旋转,平移,剪切和缩放比例。 img_minist1.py 数字识别(0-9) img_rgb2.py 彩色图片分类('airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship',...
pyStackReg提供以下五种类型的失真: 翻译刚体(平移+旋转) 缩放旋转(平移+旋转+缩放) 仿射(平移+旋转+缩放+剪切) 双线性(非线性变换;不保留直线) pyStackReg支持StackReg的全部功能以及一些其他选
【2】齐全的CAD浏览编辑:包括平移缩放、全图框选、复制剪切、布局图层、颜色线型、捕捉文字、填充等; 【3】齐全的CAD图形绘制:包括直线、圆、样条曲线、多段线、椭圆、射线等一应俱全; 【4】齐全的CAD标注测量:...
看图纸(原名非常看图)DwgSee Plus是为工程...既提供了图形平移、全屏、缩放等一般功能,又提供了独具特色的双图同步浏览功能,并支持全屏模式,方便设计和审 核人员进行双图对比查看,是工程设计人员必备的看图工具
看图纸(原名非常看图)DwgSee Plus是为工程...既提供了图形平移、全屏、缩放等一般功能,又提供了独具特色的双图同步浏览功能,并支持全屏模式,方便设计和审 核人员进行双图对比查看,是工程设计人员必备的看图工具!
【2】齐全的CAD浏览编辑:包括平移缩放、全图框选、复制剪切、布局图层、颜色线型、捕捉文字、填充等; 【3】齐全的CAD图形绘制:包括直线、圆、样条曲线、多段线、椭圆、射线等一应俱全; 【4】齐全的CAD标注测量:...
向左平移 切换下一个动画 切换下一张 - 在任务视图中切换到上一进程 向右平移 返回上一个动画 切换上一张 - 在任务视图中切换到下一进程 缩放(放大) 转到最后一页 放大 放大系统音量 - 缩放(缩小) 转到第一页 ...
【2】齐全的CAD浏览编辑:包括平移缩放、全图框选、复制剪切、布局图层、颜色线型、捕捉文字、填充等; 【3】齐全的CAD图形绘制:包括直线、圆、样条曲线、多段线、椭圆、射线等一应俱全; 【4】齐全的CAD标注...
虽然仿射几何变换仅限于平行投影,但它适用于大多数常见的几何变换,包括旋转、平移、缩放、反射、剪切等。一些常见的 3D 仿射矩阵列在本说明的底部。 如果您只想将 3D 仿射矩阵应用于 3D 图像体积中的每个 [xyz] ...
为以下操作生成变换矩阵:平移,旋转,缩放,剪切,偏斜 将多个变换矩阵合并到一个由多个矩阵组成的矩阵中 双向使用字符串: parse , render 将转换矩阵应用于点 使用示例(ES6) import { scale , rotate , ...