`
hzy3774
  • 浏览: 993876 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

Android实现图片单点旋转缩放保存-仿百度魔图

 
阅读更多

当拖动右下角区域时执行围绕图像中心旋转,缩放的操作,拖动其他区域执行平移。

采用Matrix变换实现,最后可以保存在文件。

效果如下:



 

View的代码如下:

package com.hu.imagepro;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.content.Context;
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.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.View;

import com.example.imageprocess.R;

public class ProcessView extends View{
	
	Context context = null;
	Matrix matrixPaint = null;
	Bitmap bmpMotion = null;
	Bitmap bmpRotate = null;
	Bitmap bmpBack = null;
	
	RectF rectMotionPre = null;
	RectF rectMotion = null;
	RectF rectRotateMark = null;
	RectF rectRotatePre = null;
	RectF rectRotate = null;
	
	Paint paint = null;
	PaintFlagsDrawFilter paintFilter = null;
	ViewStatus status = ViewStatus.STATUS_MOVE;
	
	PointF pointMotionMid = null;
	PointF prePoint = null;
	PointF curPoint = null;
	PointF rotateCenterP = null;
	
	String savePath = null;
	
	enum ViewStatus{
		STATUS_ROTATE,
		STATUS_MOVE,
	}

	public ProcessView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		this.context = context;
		//创建变幻图形用的Matrix
		matrixPaint = new Matrix();
		//创建画笔
		paint = new Paint();
		//画笔抗锯齿
		paint.setAntiAlias(true);
		paint.setColor(Color.BLUE);
		//设置画笔绘制空心图形
		paint.setStyle(Style.STROKE);
		try {
			//加载相应的图片资源
			bmpMotion = BitmapFactory.decodeStream(context.getAssets().open("wenzi_14.png"));
			bmpBack = BitmapFactory.decodeStream(context.getAssets().open("background.png"));
			bmpRotate = BitmapFactory.decodeResource(getResources(), R.drawable.btn_rotate_a);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//记录表情最初的矩形
		rectMotionPre = new RectF(0, 0, bmpMotion.getWidth(), bmpMotion.getHeight());
		//记录表情当前的矩形
		rectMotion = new RectF(rectMotionPre);
		//标记旋转图标位置的矩形
		rectRotateMark = new RectF(rectMotion.right - bmpRotate.getWidth() / 2,
				rectMotion.bottom - bmpRotate.getHeight() / 2,
				rectMotion.right + bmpRotate.getWidth() / 2,
				rectMotion.bottom + bmpRotate.getHeight() / 2);
		//记录旋转图标矩形最初的矩形
		rectRotatePre = new RectF(rectRotateMark);
		//记录当前旋转图标位置的矩形
		rectRotate = new RectF(rectRotateMark);
		//记录表情矩形的中点
		pointMotionMid = new PointF(bmpMotion.getWidth() / 2, bmpMotion.getHeight() / 2);
		//记录上次动作的坐标
		prePoint = new PointF();
		//记录当前动作的坐标
		curPoint = new PointF();
		//记录旋转图标中点
		rotateCenterP = new PointF(rectMotion.right, rectMotion.bottom);
		//画布参数
		paintFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
		
		savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test123.png";
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		canvas.setDrawFilter(paintFilter);
		canvas.drawBitmap(bmpBack, 0, 0, paint);
		canvas.drawBitmap(bmpMotion, matrixPaint, null);
		canvas.drawBitmap(bmpRotate, null, rectRotate, null);
//		canvas.drawRect(rectPaint, paint);
//		canvas.drawRect(rectRotate, paint);
//		canvas.drawCircle(picMidPoint.x, picMidPoint.y, 5, paint);
		super.onDraw(canvas);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		float x = event.getX();
		float y = event.getY();
		
		switch (event.getAction()) {
		//手指按下的时候
		case MotionEvent.ACTION_DOWN:
			prePoint.x = x;
			prePoint.y = y;
			//按到了旋转图标上
			if(isInRect(x, y, rectRotate)){
				status = ViewStatus.STATUS_ROTATE;
			}else{
				status = ViewStatus.STATUS_MOVE;
			}
			break;
		case MotionEvent.ACTION_UP:
			if(status == ViewStatus.STATUS_ROTATE){
				saveBitmap();
			}
			break;
		case MotionEvent.ACTION_MOVE:
			curPoint.x = x;
			curPoint.y = y;
			if(status == ViewStatus.STATUS_ROTATE){
				rectRotateMark.set(x - bmpRotate.getWidth() / 2,
						y - bmpRotate.getHeight() / 2,
						x + bmpRotate.getWidth() / 2,
						y + bmpRotate.getHeight() / 2);
				//获取旋转的角度
				float de = getPointsDegree(prePoint, pointMotionMid, curPoint);
				//获取缩放的比例
				float re = getPointsDistance(pointMotionMid, curPoint) / getPointsDistance(pointMotionMid, prePoint);
				if(re > 0.0001){
					//对Matrix进行缩放
					matrixPaint.postScale(re, re, pointMotionMid.x, pointMotionMid.y);
				}
				if(de > 0.0001 || de < -0.0001){
					//对Matrix进行旋转
					matrixPaint.postRotate(de, pointMotionMid.x, pointMotionMid.y);
				}
			}else if(status == ViewStatus.STATUS_MOVE){
				//对Matrix进行移位
				matrixPaint.postTranslate(x - prePoint.x, y - prePoint.y);
			}
			prePoint.x = x;
			prePoint.y = y;
			//将矩阵map到表情矩形上
			matrixPaint.mapRect(rectMotion, rectMotionPre);
			matrixPaint.mapRect(rectRotateMark, rectRotatePre);
			getRectCenter(rectRotateMark, rotateCenterP);
			getRectCenter(rectMotion, pointMotionMid);
			rectRotate.set(rotateCenterP.x - bmpRotate.getWidth() / 2, 
					rotateCenterP.y - bmpRotate.getHeight() / 2,
					rotateCenterP.x + bmpRotate.getWidth() / 2, 
					rotateCenterP.y + bmpRotate.getHeight() / 2);
			postInvalidate();
			break;
		default:
			break;
		}
		return true;
	}
	
	/**
	 * 将当前表情合并到背景并保存
	 */
	private void saveBitmap() {
		File f = new File(savePath);
		//使用背景图的宽高创建一张bitmap
		Bitmap bmpSave = Bitmap.createBitmap(bmpBack.getWidth(), bmpBack.getHeight(), Bitmap.Config.ARGB_8888);
		//创建canvas
		Canvas canvas = new Canvas(bmpSave);
		//将背景图和表情画在bitmap上
		canvas.drawBitmap(bmpBack, 0, 0, paint);
		canvas.drawBitmap(bmpMotion, matrixPaint, paint);
		//保存bitmap
//		canvas.save(Canvas.ALL_SAVE_FLAG); 
//		canvas.restore(); 
		try{
			FileOutputStream out = new FileOutputStream(f);
			bmpSave.compress(Bitmap.CompressFormat.PNG, 100, out);
			out.flush();
			out.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		bmpBack.recycle();
		bmpBack = bmpSave;
		//重置Matrix
		matrixPaint.reset();
		//充值旋转图标
		rectRotate.set(rectRotatePre);
	}
	
	//根据矩形获取中心点
	private void getRectCenter(RectF rect, PointF p){
		p.x = rect.left + (rect.right - rect.left) / 2;
		p.y = rect.top + (rect.bottom - rect.top) / 2;
	}
	
	//判断点是否在矩形内
	private boolean isInRect(float x, float y, RectF rect){
		boolean ret = false;
		if(x > rect.left && x < rect.right && y > rect.top && y < rect.bottom){
			ret = true;
		}
		return ret;
	}
	
	//求两点间距离
	private float getPointsDistance(PointF p1, PointF p2) {
		float ret = (float) Math.sqrt(Math.abs((p1.x - p2.x) * (p1.x - p2.x)
				+ (p1.y - p2.y) * (p1.y - p2.y)));
		return ret;
	}
	
	//求角ABC
	private float getPointsDegree(PointF a, PointF b, PointF c){
		if(Math.abs(a.x - c.x) < 2 && Math.abs(a.y - c.y) < 2){
			return 0.0f;
		}
		float ret = (float) (  Math.toDegrees(Math.atan2(c.y - b.y, c.x - b.x) 
				- Math.atan2(a.y - b.y, a.x - b.x)));
		return ret;
	}

}

 

  • 大小: 924.4 KB
分享到:
评论

相关推荐

    疯狂猜图、百度魔图和魔漫相机为啥能火.docx

    而百度魔图(原名魔图精灵)作为百度公司推出的一款多功能图片处理工具,它将图片拍摄、美化、分享与云端相册等功能融为一体。百度魔图的“PK大咖”特色功能更是吸引了众多用户。通过这一功能,用户可以与明星脸进行...

    百度魔图又名photowonder

    图片对比工具,挺好玩的

    全能魔图 v6.0.7.0.zip

    全能魔图是一款专业好用的店铺图片下载软件。软件支持淘宝、天猫、京东、阿里巴巴、国美、苏宁、当当、折800、唯品会等诸多网店,可以实现快速的将店铺首页、描述、主图等图片信息抓取出来,还支持批量操作。软件...

    Android七个最好的图片编辑软件.doc

    1. **百度魔图 (Photowonder)**:这款应用以其全面的功能深受用户喜爱。它提供了瘦脸瘦身、装饰、裁剪、调色、拼图以及多种特效,使得用户能够轻松打造出影楼级别的照片。此外,还有5GB的免费云相册空间供用户存储...

    ImageFilterForAndroid

    "ImageFilterForAndroid"项目就是一个专注于图片滤镜处理的Android库,它为开发者提供了一种简单易用的方式来实现类似百度魔图的图片特效。本文将深入探讨ImageFilterForAndroid的核心技术和应用场景,帮助开发者更...

    创新工场7大“毕业生”都去了哪里?.docx

    - 魔图精灵是一个照片美化编辑应用,还有社交图片分享平台“友图”。 - 在竞争激烈的市场环境下,选择被百度以千万美元的金额全资收购,成为百度的一部分,更名为百度魔图。 - 尽管出售价格相对较低,但魔图精灵...

    基于深度学习的图像识别进展百度的若干实践

    2. **互联网产品的集成**:百度将其先进的图像识别技术广泛应用于各类互联网产品中,如图像搜索、网页搜索、百度魔图、涂书笔记等。这些应用不仅提高了用户体验,还为企业带来了显著的价值。 3. **创新性研究项目*...

    如何看待社交图片应用?那些昙花一现的APP.docx

    1. **现象分析**:2013年以来,多款社交图片应用如疯狂猜图、百度魔图和魔漫相机等在国内市场迅速崛起,凭借社交媒体平台如微博和微信的朋友圈实现了病毒式的快速传播。然而,这些应用的生命周期普遍较短,火爆之后...

    李开复:创新工场最关键的是投资+孵化模式和团队.docx

    - **魔图精灵**:专注于移动平台图片处理解决方案。 - **行云**:从事网页游戏开发。 - **应用汇**:运营Android应用商店。 - **磊友**:专注于HTML5游戏开发。 - **点点**:提供轻博客服务。 - **知乎**:社交问答...

    ios图片简单处理

    例如,可以使用CIPhotoEffectProcess滤镜来实现类似Instagram的效果,或者使用CIColorControls调整图片的亮度、对比度和饱和度。以下是一个简单的应用滤镜的示例代码: ```swift import UIKit import CoreImage ...

    国内图片应用昙花一现:难成生态 仍是工具.docx

    国内图片应用在短时间内经历了迅速崛起和快速衰落的过程,像“疯狂猜图”、“百度魔图”和“魔漫相机”等应用曾一度火爆,但很快便淡出了人们的视野。这一现象揭示了国内图片应用在生态构建上的挑战。 1. **社交...

    图片分享社区:Flickr后图片社交二次革命.docx

    6. **产品整合策略**:友图从图像增强工具魔图精灵派生而来,计划通过让用户在两者之间自由切换,或合并产品,以促进用户从魔图精灵向友图的转移。 综上所述,图片分享社区的二次革命是由移动设备的普及和社交媒体...

    公司简介、文化、营销案例之XXXX世界末日.pptx

    涵盖搜索服务(如网页、视频、音乐、新闻、地图)、导航服务(如hao123)、社区服务(如百度空间、文库、贴吧、百科)、游戏娱乐(如百度游戏、悠洋游戏)、移动服务(如手机输入法、手机地图、百度魔图)、站长与...

    大数据应用基础-图像数据.pptx

    百度、谷歌等公司采用深度神经网络(DNN)进行图像搜索和分类,如百度的图片搜索可以根据元素识别生成诗句,而Orbeus和Madbits则能自动为照片添加标签,方便用户搜索。同时,Cortica等企业利用图像信息改进互联网...

    大数据应用基础-图像数据25.pptx

    企业如Emotient、Affectiva、百度魔图以及Face++等提供了相关技术和服务。此外,人脸识别技术还可用于安全验证,如FaceEID、云脸应用锁等,以及疲劳驾驶检测等智能监控系统。 物品识别是另一个重要领域,Camfind、...

    The Generalized Petersen Graph P(n,7) is ((3n+6)/2,3)-Antimagic

    7) is ((3n+6)/2,3)-Antimagic",描述是"Generalized Petersen Graph P(n,7) is ((3n+6)/2,3)-Antimagic",而从【部分内容】提供的信息中可以提取出关键的学术知识点如下: 1. 抗魔图(Antimagic Graph)的定义:一...

    新型无线数码变画灯箱广告媒体投资计划书.doc

    沈阳魔图灯箱开发有限公司凭借其在技术创新上的深厚积累,研发出了一种新型无线数码变画灯箱广告媒体——“魔图”第二代数码变画灯箱。这款产品的问世,不仅为广告展示技术注入了新鲜血液,更为投资商们开辟了一个...

Global site tag (gtag.js) - Google Analytics