android开发基础10-基本图形图像处理

2024-01-26 18:50

本文主要是介绍android开发基础10-基本图形图像处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

画笔和画布的使用

画笔 : Paint类;画笔的作用:颜色,透明度,画笔粗细,填充样式
画布:Canvas类;可以改变画布的尺寸和颜色

使用画笔和画布的步骤:
1、创建一个类,继承于View类
2、重写onDraw()方法
3、再把自定位的View添加到Activity中

实例:画一个橙色的矩形

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);FrameLayout fragment = (FrameLayout) findViewById(R.id.frameLayout);  //获取帧布局管理器fragment.addView(new MyView(this));  //将自定义视图的内部类添加到布局管理器中}private class MyView extends View {public MyView(Context context) {super(context);}@Overrideprotected void onDraw(Canvas canvas) {  //重写onDraw()方法Paint paint = new Paint();           //定义一个默认的画笔//线性渐变Shader shader = new LinearGradient(0, 0, 100, 100,Color.RED, Color.GREEN, Shader.TileMode.MIRROR);paint.setShader(shader);                            //为画笔设置渐变器canvas.drawRect(10, 10, 280, 150, paint);                //绘制矩形super.onDraw(canvas);}}
}

绘制几何图形

Canvas类提供了很多方法绘制几何图形
drawArc
drawCircle
drawLine
drawRect
drawRoundRect

实例:绘制android机器人

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);FrameLayout frameLayout= (FrameLayout) findViewById(R.id.frameLayout);  //获取帧布局管理器frameLayout.addView(new MyView(this));  //将自定义视图的内部类添加到布局管理器中}private class MyView extends View {public MyView(Context context) {super(context);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Paint paint=new Paint();	//默认设置创建一个画笔paint.setAntiAlias(true);	//使用抗锯齿功能paint.setColor(0xFFA4C739);	//设置画笔的颜色为绿色//绘制机器人的头RectF rectf_head=new RectF(10, 10, 100, 100);rectf_head.offset(90, 20);canvas.drawArc(rectf_head, -10, -160, false, paint);	//绘制弧//绘制眼睛paint.setColor(Color.WHITE);	//设置画笔的颜色为白色canvas.drawCircle(125, 53, 4, paint);	//绘制圆canvas.drawCircle(165, 53, 4, paint);	//绘制圆paint.setColor(0xFFA4C739);	//设置画笔的颜色为绿色//绘制天线paint.setStrokeWidth(2);	//设置笔触的宽度canvas.drawLine(110, 15, 125, 35, paint);	//绘制线canvas.drawLine(180, 15, 165, 35, paint);	//绘制线//绘制身体canvas.drawRect(100, 75, 190, 150, paint);	//绘制矩形RectF rectf_body=new RectF(100,140,190,160);canvas.drawRoundRect(rectf_body, 10, 10, paint);	//绘制圆角矩形//绘制胳膊RectF rectf_arm=new RectF(75,75,95,140);canvas.drawRoundRect(rectf_arm, 10, 10, paint);	//绘制左侧的胳膊rectf_arm.offset(120, 0);							//设置在X轴上偏移120像素canvas.drawRoundRect(rectf_arm, 10, 10, paint);	//绘制右侧的胳膊//绘制腿RectF rectf_leg=new RectF(115,150,135,200);canvas.drawRoundRect(rectf_leg, 10, 10, paint);	//绘制左侧的腿rectf_leg.offset(40, 0);							//设置在X轴上偏移40像素canvas.drawRoundRect(rectf_leg, 10, 10, paint);	//绘制右侧的腿}}
}

绘制文本

使用Canvas类的drawText()方法实现

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获取布局文件中添加的帧布局管理器FrameLayout frameLayout=(FrameLayout)findViewById(R.id.frameLayout);//将自定义的MyView视图添加到帧布局管理器中frameLayout.addView(new MyView(this));}private class MyView extends View{public MyView(Context context) {super(context);}@Overrideprotected void onDraw(Canvas canvas) {Paint paintText=new Paint();						//创建一个采用默认设置的画笔paintText.setColor(Color.BLACK);						//设置画笔颜色paintText.setTextAlign(Paint.Align.LEFT);				//设置文字左对齐paintText.setTextSize(12);								//设置文字大小paintText.setAntiAlias(true);						  //使用抗锯齿功能canvas.drawText("不,我不想去!", 245, 45, paintText);	//通过drawText()方法绘制文字canvas.drawText("你想和我一起",175,160,paintText);  //通过drawText()方法绘制文字canvas.drawText("去探险吗?",175,175,paintText);    //通过drawText()方法绘制文字}}
}

绘制图片

需要创建位图对象Bitmap
BitmapFactory类:
decodeFile()
decodeResource()
decodeStream()
1、通过图片文件创建
2、通过输入流创建

Bitmap类:
createBitmap()
compress() 压缩Bitmap对象并保存到文件输出流中
createScaledBitmap() 将源位图缩放并创建新的Bitmap对象
1、同一张图上挖出一部分进行创建
2、把源位图缩放生成
3、使用颜色数组创建

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获取布局文件中添加的帧布局管理器FrameLayout frameLayout = (FrameLayout) findViewById(R.id.frameLayout);frameLayout.addView(new MyView(this)); //将自定义的MyView视图添加到帧布局管理器中}private class MyView extends View {public MyView(Context context) {super(context);}@Overrideprotected void onDraw(Canvas canvas) {Paint paint = new Paint();  //创建一个采用默认设置的画笔String path = Environment.getExternalStorageDirectory() + "/img01.jpg";  //指定图片文件的路径Bitmap bm = BitmapFactory.decodeFile(path);  //获取图片文件对应的Bitmap对象canvas.drawBitmap(bm, 0, 30, paint);   //将获取的Bitmap对象绘制在画布的指定位置Rect src = new Rect(105, 70, 220, 170);  //设置挖取的区域Rect dst = new Rect(350, 90, 465, 190);  //设置绘制的区域canvas.drawBitmap(bm, src, dst, paint);  //绘制挖取到的图像}}}

绘制路径

通过Path类绘制路径
在这里插入图片描述

public class DrawView extends View {private int view_width = 0;  //屏幕的宽度private int view_height = 0;  //屏幕的高度private float preX;  //起始点的X坐标值private float preY;  //起始点的y坐标值private Path path;  //路径public Paint paint = null;  //画笔Bitmap cacheBitmap = null;  //定义一个内存中的图片,该图片将作为缓冲区Canvas cacheCanvas = null;  // 定义cacheBitmap上的Canvas对象public DrawView(Context context, AttributeSet set) {  //构造方法super(context, set);view_width = context.getResources().getDisplayMetrics().widthPixels;  // 获取屏幕的宽度view_height = context.getResources().getDisplayMetrics().heightPixels;  // 获取屏幕的高度System.out.println(view_width + "*" + view_height);  //屏幕宽高// 创建一个与该View相同大小的缓存区cacheBitmap = Bitmap.createBitmap(view_width, view_height, Bitmap.Config.ARGB_8888);cacheCanvas = new Canvas();  //创建一个新的画布path = new Path();  //实例化路径cacheCanvas.setBitmap(cacheBitmap);  // 在cacheCanvas上绘制cacheBitmappaint = new Paint();  //实例化画笔paint.setColor(Color.RED);  // 设置默认的画笔颜色// 设置画笔风格paint.setStyle(Paint.Style.STROKE);  //设置填充方式为描边paint.setStrokeWidth(2); // 设置默认笔触的宽度为1像素paint.setAntiAlias(true); // 使用抗锯齿功能}@Overrideprotected void onDraw(Canvas canvas) {  //重写onDraw()方法super.onDraw(canvas);canvas.drawBitmap(cacheBitmap, 0, 0, null);  //绘制cacheBitmapcanvas.drawPath(path, paint);  //绘制路径}@Overridepublic boolean onTouchEvent(MotionEvent event) {// 获取触摸事件的发生位置float x = event.getX();  //获取x坐标float y = event.getY();  //获取y坐标switch (event.getAction()) {case MotionEvent.ACTION_DOWN: //当手指按下时path.moveTo(x, y);  // 将绘图的起始点移到(x,y)坐标点的位置preX = x;preY = y;break;case MotionEvent.ACTION_MOVE: //根据触摸过程与位置绘制线条float dx = Math.abs(x - preX);  //计算x值的移动距离float dy = Math.abs(y - preY);  //计算y值的移动距离if (dx >= 5 || dy >= 5) {  //判断是否在允许的范围内path.quadTo(preX, preY, (x + preX) / 2, (y + preY) / 2);  //贝塞尔曲线preX = x;preY = y;}break;case MotionEvent.ACTION_UP: //当手指抬起时cacheCanvas.drawPath(path, paint); //绘制路径path.reset();  //重置路径break;}invalidate();  //刷新return true;  // 返回true表明处理方法已经处理该事件}public void clear() {  //清空写字板if (cacheCanvas != null) {  //如果绘制路径不为空path.reset();            //重置路径cacheCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);invalidate();   //刷新}}
}
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);final DrawView drawView= (DrawView) findViewById(R.id.dv);  //获取自定义的绘图视图ImageButton button= (ImageButton) findViewById(R.id.btn_clear);  //获取清空按钮button.setOnClickListener(new View.OnClickListener() {  //为按钮设置监听事件@Overridepublic void onClick(View v) {drawView.clear();  //调用清除方法}});}
}

逐帧动画

1、动画资源文件
2、在布局文件中使用动画资源文件

1、在res/anim目录下创建fairy.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/img001" android:duration="60"/><item android:drawable="@drawable/img002" android:duration="60"/><item android:drawable="@drawable/img003" android:duration="60"/><item android:drawable="@drawable/img004" android:duration="60"/><item android:drawable="@drawable/img005" android:duration="60"/><item android:drawable="@drawable/img006" android:duration="60"/>
</animation-list>

2、在布局管理器中引用fairy

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutandroid:id="@+id/linearLayout"xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:background="@anim/fairy"tools:context="com.mingrisoft.MainActivity"></LinearLayout>

3、通知逐帧动画的播放和停止

public class MainActivity extends AppCompatActivity {private boolean flag = true;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);LinearLayout linearLayout= (LinearLayout) findViewById(R.id.linearLayout); //获取布局管理器//获取AnimationDrawable对象final AnimationDrawable anim= (AnimationDrawable) linearLayout.getBackground();linearLayout.setOnClickListener(new View.OnClickListener() {  //为布局管理器添加单击事件@Overridepublic void onClick(View v) {if(flag){anim.start(); //开始播放动画flag=false;}else {anim.stop();  //停止播放动画flag=true;}}});}
}

补间动画

在设计动画时,定义一个起始帧和结束帧,之间的会自动生成
在res/anim下创建
1、透明度渐变动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><alpha android:fromAlpha="0"android:toAlpha="1"android:duration="4000"/>
</set>
Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha);
imageView.startAnimation(anim); //开启动画

2、旋转动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><rotateandroid:fromDegrees="0"android:toDegrees="360"android:pivotX="50%"android:pivotY="50%"android:duration= "2000" />
</set>

3、缩放动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><scale android:fromXScale="0.0"android:fromYScale="0.0"android:pivotX="50%"android:pivotY="50%"android:toXScale="1.0"android:toYScale="1.0"android:duration="2000"></scale>
</set>

4、平移动画

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><translateandroid:fromXDelta="0"android:fromYDelta="0"android:toXDelta="300"android:duration= "2000"android:toYDelta="300" />
</set>

实例 :淡入淡出补间效果

public class MainActivity extends AppCompatActivity implements GestureDetector.OnGestureListener {ViewFlipper flipper; //定义ViewFlipperGestureDetector detector; //定义手势检测器Animation[] animation = new Animation[4];//定义动画数组,为ViewFlipper指定切换动画final int distance = 50; //定义手势动作两点之间最小距离//定义图片数组private int[] images = new int[]{R.drawable.img01, R.drawable.img02, R.drawable.img03,R.drawable.img04, R.drawable.img05, R.drawable.img06, R.drawable.img07, R.drawable.img08,R.drawable.img09,};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);detector = new GestureDetector(this, this); //创建手势检测器flipper = (ViewFlipper) findViewById(R.id.flipper); //获取ViewFlipperfor (int i = 0; i < images.length; i++) {ImageView imageView = new ImageView(this);imageView.setImageResource(images[i]);flipper.addView(imageView); //加载图片}//初始化动画数组animation[0] = AnimationUtils.loadAnimation(this, R.anim.anim_alpha_in);     //淡入动画animation[1] = AnimationUtils.loadAnimation(this, R.anim.anim_alpha_out);      //淡出动画animation[2] = AnimationUtils.loadAnimation(this, R.anim.anim_scale_in);      //放大进入动画animation[3] = AnimationUtils.loadAnimation(this, R.anim.anim_scale_out);  //缩小退出动画}@Overridepublic boolean onDown(MotionEvent e) {return false;}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {return false;}@Overridepublic void onLongPress(MotionEvent e) {}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {/*如果第一个触点事件的X坐标到第二个触点事件的X坐标的距离超过distance就是从右向左滑动*/if (e1.getX() - e2.getX() > distance) {//为flipper设置切换的动画效果flipper.setInAnimation(animation[0]);flipper.setOutAnimation(animation[1]);flipper.showPrevious();return true;/*如果第二个触点事件的X坐标到第一个触点事件的X坐标的距离超过distance就是从左向右滑动*/} else if (e2.getX() - e1.getX() > distance) {//为flipper设置切换的动画flipper.setInAnimation(animation[2]);flipper.setOutAnimation(animation[3]);flipper.showNext();return true;}return false;}@Overridepublic boolean onTouchEvent(MotionEvent event) {//将该Activity上的触碰事件交给GestureDetector处理return detector.onTouchEvent(event);}
}

这篇关于android开发基础10-基本图形图像处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/647735

相关文章

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Python自动化处理手机验证码

《Python自动化处理手机验证码》手机验证码是一种常见的身份验证手段,广泛应用于用户注册、登录、交易确认等场景,下面我们来看看如何使用Python自动化处理手机验证码吧... 目录一、获取手机验证码1.1 通过短信接收验证码1.2 使用第三方短信接收服务1.3 使用ADB读取手机短信1.4 通过API获取

Python中多线程和多进程的基本用法详解

《Python中多线程和多进程的基本用法详解》这篇文章介绍了Python中多线程和多进程的相关知识,包括并发编程的优势,多线程和多进程的概念、适用场景、示例代码,线程池和进程池的使用,以及如何选择合适... 目录引言一、并发编程的主要优势二、python的多线程(Threading)1. 什么是多线程?2.

Python自动化Office文档处理全攻略

《Python自动化Office文档处理全攻略》在日常办公中,处理Word、Excel和PDF等Office文档是再常见不过的任务,手动操作这些文档不仅耗时耗力,还容易出错,幸运的是,Python提供... 目录一、自动化处理Word文档1. 安装python-docx库2. 读取Word文档内容3. 修改

使用Go语言开发一个命令行文件管理工具

《使用Go语言开发一个命令行文件管理工具》这篇文章主要为大家详细介绍了如何使用Go语言开发一款命令行文件管理工具,支持批量重命名,删除,创建,移动文件,需要的小伙伴可以了解下... 目录一、工具功能一览二、核心代码解析1. 主程序结构2. 批量重命名3. 批量删除4. 创建文件/目录5. 批量移动三、如何安

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

MyBatis-Flex BaseMapper的接口基本用法小结

《MyBatis-FlexBaseMapper的接口基本用法小结》本文主要介绍了MyBatis-FlexBaseMapper的接口基本用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具... 目录MyBATis-Flex简单介绍特性基础方法INSERT① insert② insertSelec

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解