`
玩野大人
  • 浏览: 14267 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

图片缩放、平移、剪切

阅读更多
盯了两天代码才实现的功能我不得不把他写上博客,共享!主要是实现从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;
	}
		
}

1
0
分享到:
评论
1 楼 enjoylrx 2011-10-12  
你好,可以发工程文件或者贴上string.xml可以吗
我的email:jeonhei.lam.g@gmail.com
谢谢

相关推荐

    Android 仿微信上传头像自定义(剪切、平移,缩放)

    此demo是模仿微信的上传头像可以自定义的对图片进行缩放,平移后剪切,也解决了三星的剪切图片时旋转问题,里面有设置图片旋转的相关代码,适合很多机型。

    Android 上传头像自定义(剪切、平移,缩放)

    此资源根据模仿微信自定义裁剪图片的,实现了拍照上传裁剪和选择相册裁剪在三星、华为、小米、魅族手机,解决了三星手机上面的旋转问题。由于实现此功能浪费了我大半天时间,就在这里讨了2积分的赏!

    yolo离线数据增强代码

    1. 像素级:HSV增强、旋转、平移、缩放、剪切、透视、翻转等 2. 图片级:MixUp、Cutout、CutMix、Mosaic、Copy-Paste等 3. 基本图片处理方法:将图像的最长边缩放到640,短边填充到640等方法。 可供使用者完成开发...

    react-native-image-cropper:使用缩放和平移裁剪图像

    该图片裁剪器基于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-...

    Crop-Image

    实现了图片经过平移,缩放,旋转手势后的完美剪切

    微信小程序-canvas-剪切保存图片

    一个微信小程序demo,用户可以上传一张图片,在canvas画布上展示,然后可以平移、单指旋转、双指缩放图片,最后将canvas区域内的图片内容保存到本地相册。采用了微信开发者文档的最新api,能够兼容大多数的场景,并...

    在WPF中使用opencvsharp操作图像.rar

    【实例简介】 在WPF中使用opencvsharp操作图像,实现加载、翻转、旋转、缩放、平移、剪切、保存等操作。

    Android中Bitmap常见的一些操作:缩放、裁剪、旋转和偏移

    Bitmap相信对各位Android开发者们来说都不陌生,用它可以获取图片信息,进行图片剪切、平移、旋转、缩放等操作,并可以指定格式保存图片文件。本文将对它的一些常见操作进行总结,下面话不多说了,来一起看看详细的...

    QTransformtracker

    qtransformtracker类能够动态的平移和缩放,还支持动态的旋转(需按下Ctrl键),按比例缩放,剪切变换,限制水平和垂直移动等。附demo,在VS2005环境下编译通过,能正常运行。

    深度学习天气照片数据集,分别包括clody,haze,sunrise,snow,shine,rain,thunder

    数据扩充涉及对现有训练数据添加随机旋转,平移,剪切和缩放比例。 img_minist1.py 数字识别(0-9) img_rgb2.py 彩色图片分类('airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship',...

    pystackreg:python扩展,用于自动将源图像或堆栈(影片)对齐到目标图像参考帧

    pyStackReg提供以下五种类型的失真: 翻译刚体(平移+旋转) 缩放旋转(平移+旋转+缩放) 仿射(平移+旋转+缩放+剪切) 双线性(非线性变换;不保留直线) pyStackReg支持StackReg的全部功能以及一些其他选

    迷你看图下载

    【2】齐全的CAD浏览编辑:包括平移缩放、全图框选、复制剪切、布局图层、颜色线型、捕捉文字、填充等; 【3】齐全的CAD图形绘制:包括直线、圆、样条曲线、多段线、椭圆、射线等一应俱全; 【4】齐全的CAD标注测量:...

    看图纸(DwgSee Plus) 2.3(原名非常看图)

    看图纸(原名非常看图)DwgSee Plus是为工程...既提供了图形平移、全屏、缩放等一般功能,又提供了独具特色的双图同步浏览功能,并支持全屏模式,方便设计和审 核人员进行双图对比查看,是工程设计人员必备的看图工具

    DwgSee看图纸(CADSee Plus) v7.1.0.rar

    看图纸(原名非常看图)DwgSee Plus是为工程...既提供了图形平移、全屏、缩放等一般功能,又提供了独具特色的双图同步浏览功能,并支持全屏模式,方便设计和审 核人员进行双图对比查看,是工程设计人员必备的看图工具!

    CAD迷你画图

    【2】齐全的CAD浏览编辑:包括平移缩放、全图框选、复制剪切、布局图层、颜色线型、捕捉文字、填充等; 【3】齐全的CAD图形绘制:包括直线、圆、样条曲线、多段线、椭圆、射线等一应俱全; 【4】齐全的CAD标注测量:...

    gesture-control:用于软件创新竞赛的手势控制系统

    向左平移 切换下一个动画 切换下一张 - 在任务视图中切换到上一进程 向右平移 返回上一个动画 切换上一张 - 在任务视图中切换到下一进程 缩放(放大) 转到最后一页 放大 放大系统音量 - 缩放(缩小) 转到第一页 ...

    MiniCADDraw 迷你CAD

    【2】齐全的CAD浏览编辑:包括平移缩放、全图框选、复制剪切、布局图层、颜色线型、捕捉文字、填充等; 【3】齐全的CAD图形绘制:包括直线、圆、样条曲线、多段线、椭圆、射线等一应俱全; 【4】齐全的CAD标注...

    使用仿射矩阵重采样体积或图像:使用仿射矩阵将 3D vol 或 2D img 转换为具有相应仿射矩阵的正交图像。-matlab开发

    虽然仿射几何变换仅限于平行投影,但它适用于大多数常见的几何变换,包括旋转、平移、缩放、反射、剪切等。一些常见的 3D 仿射矩阵列在本说明的底部。 如果您只想将 3D 仿射矩阵应用于 3D 图像体积中的每个 [xyz] ...

    transformation-matrix:用ES6语法编写的Javascript同构2D仿射变换。 使用这个经过全面测试的库来处理变换矩阵!

    为以下操作生成变换矩阵:平移,旋转,缩放,剪切,偏斜 将多个变换矩阵合并到一个由多个矩阵组成的矩阵中 双向使用字符串: parse , render 将转换矩阵应用于点 使用示例(ES6) import { scale , rotate , ...

Global site tag (gtag.js) - Google Analytics