初学Android 图形图像之使用drawBitmapMesh扭曲图像 三十二

Canvas提供了一个方法
drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,int colorffset,Paint paint) 
这个方法可以对bitmap进行扭曲
参数说明如下:
bitmap     需要扭曲的源位图
meshWidth   控制在横向上把该源位图划成成多少格
meshHeight   控制在纵向上把该源位图划成成多少格 
verts      长度为(meshWidth + 1) * (meshHeight + 1) * 2的数组,它记录了扭曲后的位图各顶点位置
vertOffset         控制verts数组中从第几个数组元素开始才对bitmap进行扭曲

下面是扭曲一张风景图片的例子

package WangLi.Graphics.WarpTest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class WarpTest extends Activity {
    /** Called when the activity is first created. */
    private Bitmap bitmap;
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this,R.drawable.psb));
    }
	private class MyView extends View
	{
		//定义两个常量,这两个常量指定该图片横向,纵向上都被划分为20格
		private final int WIDTH = 20;
		private final int HEIGHT = 20;
		//记录该图片上包含441个顶点
		private final int COUNT = (WIDTH + 1) * (HEIGHT + 1);
		//定义一个数组,记录Bitmap上的21*21个点的坐标
		private final float[] verts = new float[COUNT * 2];
		//定义一个数组,记录Bitmap上的21*21个点经过扭曲后的坐标
		//对图片扭曲的关键就是修改该数组里元素的值
		private final float[] orig = new float[COUNT * 2];
		public MyView(Context context, int drawableId) {
			super(context);
			setFocusable(true);
			//根据指定资源加载图片
			bitmap = BitmapFactory.decodeResource(getResources(), drawableId);
			//获取图片宽度和高度
			float bitmapWidth = bitmap.getWidth();
			float bitmapHeight = bitmap.getHeight();
			int index = 0;
			for(int y = 0; y <= HEIGHT; y++)
			{
				float fy = bitmapHeight * y / HEIGHT;
				for(int x = 0 ; x <= WIDTH; x++)
				{
					float fx = bitmapWidth * x / WIDTH;
					//初始化orig,verts数组
					//初始化,orig,verts两个数组均匀地保存了21 * 21个点的x,y坐标 
					orig[index * 2 + 0] = verts[index * 2 + 0] = fx;
					orig[index * 2 + 1] = verts[index * 2 + 1] = fy;
					index += 1;
				}
			}
			//设置背景色
			setBackgroundColor(Color.WHITE);
		}
		protected void onDraw(Canvas canvas)
		{
			//对bitmap按verts数组进行扭曲
			//从第一个点(由第5个参数0控制)开始扭曲
			canvas.drawBitmapMesh(bitmap, WIDTH, HEIGHT, verts, 0, null, 0, null);
		}
		//工具方法,用于根据触摸事件的位置计算verts数组里各元素的值
		private void warp(float cx, float cy)
		{
			for(int i = 0; i < COUNT * 2; i += 2)
			{
				float dx = cx - orig[i + 0];
				float dy = cy - orig[i + 1];
				float dd = dx * dx + dy * dy;
				//计算每个坐标点与当前点(cx,cy)之间的距离
				float d = (float)Math.sqrt(dd);
				//计算扭曲度,距离当前点(cx,cy)越远,扭曲度越小
				float pull = 80000 / ((float)(dd * d));
				//对verts数组(保存bitmap 上21 * 21个点经过扭曲后的坐标)重新赋值
				if(pull >= 1)
				{
					verts[i + 0] = cx;
					verts[i + 1] = cy;
				}
				else
				{
					//控制各顶点向触摸事件发生点偏移
					verts[i + 0] = orig[i + 0] + dx * pull;
					verts[i + 1] = orig[i + 1] + dx * pull;
				}
			}
			//通知View组件重绘
			invalidate();
		}
		public boolean onTouchEvent(MotionEvent event)
		{
			//调用warp方法根据触摸屏事件的坐标点来扭曲verts数组
			warp(event.getX() , event.getY());
			return true;
		}
	}
}

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

原文地址:https://www.cnblogs.com/swdhywhd/p/10311275.html

时间: 2024-11-09 02:58:20

初学Android 图形图像之使用drawBitmapMesh扭曲图像 三十二的相关文章

[原创]ActionScript3游戏中的图像编程(连载三十二)

2.2.5 投影距离的模拟 Photoshop投影样式面板的下一个属性是距离,它也存在于Flash的投影滤镜选项中.两者初始值一致,经笔者测试,两者在效果实现和数值意义方面基本一致.Flash不需要对默认参数进行更改. 下一项是扩展,乍一看,在Flash中并没有找到对应项.但仔细观察,在Photoshop投影样式的基础选项里,除了alpha以外,就只剩该属性用了百分比. [原创]ActionScript3游戏中的图像编程(连载三十二),布布扣,bubuko.com

(转载)Android项目实战(三十二):圆角对话框Dialog

Android项目实战(三十二):圆角对话框Dialog 前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话框的"确定"按钮 难点:1.对话框边框圆角显示 2.考虑到提示文本字数不确定,在不影响美观的情况下,需要在一行内显示提示的文字信息   3.设置对话框的宽和高 技术储备: 1.安卓开发_使用AlertDialog实现对话框    知道AlertDialog有setView(view) ,Dia

Android项目实战(三十二):圆角对话框Dialog

原文:Android项目实战(三十二):圆角对话框Dialog 前言: 项目中多处用到对话框,用系统对话框太难看,就自己写一个自定义对话框. 对话框包括:1.圆角 2.app图标 , 提示文本,关闭对话框的"确定"按钮 难点:1.对话框边框圆角显示 2.考虑到提示文本字数不确定,在不影响美观的情况下,需要在一行内显示提示的文字信息   3.设置对话框的宽和高 技术储备: 1.安卓开发_使用AlertDialog实现对话框    知道AlertDialog有setView(view) ,

Android开发笔记(一百三十二)矢量图形与矢量动画

矢量图形VectorDrawable 与水波图形RippleDrawable一样,矢量图形VectorDrawable也是Android5.0之后新增的图形类.矢量图不同于一般的图形,它是由一系列几何曲线构成的图像,这些曲线以数学上定义的坐标点连接而成.具体到实现上,则需开发者提供一个xml格式的矢量图形定义,然后系统根据矢量定义自动计算该图形的绘制区域.因为绘图结果是动态计算得到,所以不管缩放到多少比例,矢量图形都会一样的清晰,不像位图那样拉大后会变模糊. 矢量图形的xml定义有点复杂,其结构

使用drawBitmapMesh扭曲图像

Canvas提供了一个drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset, paint)方法,该方法可以对Bitmap进行扭曲,实现“水波荡漾”.“风吹旗帜”等各种扭曲效果. drawBitmapMesh方法的关键参数说明: bitmap:指定需要扭曲的源位图. meshWidth:该参数控制在横向上把该源位图划分成多少格. meshHeight:该参数控制在纵向上把该源位图划分

从零开始学android&lt;chronometer计时器组件.三十二.&gt;

计时器来计算每个运动员所消耗的时间等,而在Android系统之中,这种计时的功能就可以使用Chronometer组件,此类的继承结构如下所示: 2java.lang.Object ? android.view.View ? android.widget.TextView ? android.widget.Chronometer 常见的方法 1 public Chronometer(Context context) 构造 创建Chronometer对象 2 public long getBase(

Android开发本地及网络Mp3音乐播放器(十二)创建NetMusicListAdapter、SearchResult显示网络音乐列表

实现功能: 实现NetMusicListAdapter(网络音乐列表适配器) 实现SearchResult(搜索音乐对象) 使用Jsoup组件请求网络,并解析音乐数据,并,音乐数据加载到列表中 实现FooterView 截止到目前的源码下载: http://download.csdn.net/detail/iwanghang/9507635 Jsoup组件导入: AndroidStudio简单快速导入GitHub中的第三方组件 : http://blog.csdn.net/iwanghang/a

Android的SeekBar和RateBar的使用-android学习之旅(三十二)

SeekBar简介 SeekBar允许用户拖动,进行调节经常用于音量调节等方面. android:thumb设置drawable对象来表示拖动的物体. setOnSeekBarChangeListener()设置SeekBar的改变. 代码示例 package peng.liu.test; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.Men

Android笔记三十二.Android位置服务及核心API

一.位置服务概念 1.位置服务 位置服务(Location-Based Services,LBS),又称定位服务或基于位置的服务,融合了GPS定位.移动通信.导航等多种技术,提供了与个空间位置相关的综合应用服务. 2.GPS与网络位置提供器 Android平台支持提供位置服务的API,可以利用GPS(Global Positioning System,全球定位系统)和Network Location Provider(网络位置提供器)来获得用户的位置. (1)GPS相对来说更精确,但它只能在户外