Android studio之图形与图像处理

Bitmap bitmap = drawable.getBitmap();

(3)下面我们用以上知识实现一个图片查看器

我们这个应用十分简单,仅仅包括一个按钮和一个ImageView,当我们点击按钮时候,程序会自动去搜索目录中的下一张图片:

关键代码如下:

import android.app.Activity;

import android.content.res.AssetManager;

import android.graphics.BitmapFactory;

import android.graphics.drawable.BitmapDrawable;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ImageView;

import java.io.IOException;

import java.io.InputStream;

public class MainActivity extends Activity

{

String[] images = null;

AssetManager assets = null;

int currentImg = 0;

ImageView image;

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

image = (ImageView) findViewById(R.id.image);

try

{

assets = getAssets();

// 获取目录下所有文件(assets下)

images = assets.list(“”);

}

catch (IOException e)

{

e.printStackTrace();

}

final Button next = (Button) findViewById(R.id.next);

// 为next按钮绑定事件监听器,该监听器将会查看下一张图片

next.setOnClickListener(new OnClickListener()

{

@Override

public void onClick(View sources)

{

if (currentImg >= images.length)

{

currentImg = 0;

}

// 找到下一个图片文件

while (!images[currentImg].endsWith(“.png”)

&& !images[currentImg].endsWith(“.jpg”)

&& !images[currentImg].endsWith(“.gif”))

{

currentImg++;

if (currentImg >= images.length)

{

currentImg = 0;

}

}

InputStream assetFile = null;

try

{

assetFile = assets.open(images[currentImg++]);

}

catch (IOException e)

{

e.printStackTrace();

}

BitmapDrawable bitmapDrawable = (BitmapDrawable) image

.getDrawable();

if (bitmapDrawable != null

&& !bitmapDrawable.getBitmap().isRecycled()) // ①

{

bitmapDrawable.getBitmap().recycle();

}

// 改变ImageView显示的图片

image.setImageBitmap(BitmapFactory

.decodeStream(assetFile)); // ②

}

});

}

}

结果Gif

在这里插入图片描述

二、绘图

在为我们的应用界面添砖加瓦的过程中,除了可以使用已有的图片外,Android应用还经常需要在运行过程中动态的生成图片,而这样就需要借助于Android的绘图支持了。

(1)绘图基础——Canvas、Paint

Android的绘图与Swing中的绘图思路类似即开发一个自定义类,然后让该类继承JPanel,之后重写其中的paint(Graphics g)方法即可。而我们Android中的绘图应继承View组件,并重写其中的onDraw(Canvas canvas)即可,光说不练假把式,接下来我们用一段代码绘制几个集合图形。

关键代码如下:

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.LinearGradient;

import android.graphics.Paint;

import android.graphics.Path;

import android.graphics.RectF;

import android.graphics.Shader;

import android.util.AttributeSet;

import android.view.View;

public class MyView extends View

{

public MyView(Context context, AttributeSet set)

{

super(context, set);

}

@Override

// 重写该方法,进行绘图

protected void onDraw(Canvas canvas)

{

super.onDraw(canvas);

canvas.drawColor(Color.WHITE);

Paint paint = new Paint();

paint.setAntiAlias(true);

paint.setColor(Color.BLUE);

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(4);

int viewWidth = this.getWidth();

// 绘制圆形

canvas.drawCircle(viewWidth / 10 + 10, viewWidth / 10 + 10

, viewWidth / 10, paint);

// 绘制正方形

canvas.drawRect(10 , viewWidth / 5 + 20 , viewWidth / 5 + 10

, viewWidth * 2 / 5 + 20 , paint);

// 绘制圆形

canvas.drawCircle(viewWidth * 3 / 10 + 20, viewWidth / 10 + 10

, viewWidth / 10, paint);

// 绘制正方形

canvas.drawRect(viewWidth / 5 + 20 , viewWidth / 5 + 20

, viewWidth * 2 / 5 + 20 , viewWidth * 2 / 5 + 20 , paint);

// 为Paint设置渐变器

Shader mShader = new LinearGradient(0, 0, 40, 60

, new int[] {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW }

, null , Shader.TileMode.REPEAT);

paint.setShader(mShader);

//设置阴影

paint.setShadowLayer(25 , 20 , 20 , Color.GRAY);

// 绘制圆形

canvas.drawCircle(viewWidth / 2 + 30, viewWidth / 10 + 10

, viewWidth / 10, paint);

// 绘制正方形

canvas.drawRect(viewWidth * 2 / 5 + 30 , viewWidth / 5 + 20

, viewWidth * 3 / 5 + 30 , viewWidth * 2 / 5 + 20 , paint);

canvas.drawText(getResources().getString(R.string.circle)

, 60 + viewWidth * 3 / 5, viewWidth / 10 + 10, paint);

canvas.drawText(getResources().getString(R.string.square)

, 60 + viewWidth * 3 / 5, viewWidth * 3 / 10 + 20, paint);

}

}

结果截图如下:

在这里插入图片描述

(2)Path类

Android提供的Path是一个非常有用的类,它可以在View上将几个点连成一条路径,然后可以调用Canvas中的drawPath(path,paint)方法沿着该路径进行绘图,这些所谓的绘图效果说起来大家很难理解,下面我们通过一段代码来让大家更好的理解一下这些效果,这个应用绘制了7条路径:

关键代码如下:

import android.app.Activity;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.ComposePathEffect;

import android.graphics.CornerPathEffect;

import android.graphics.DashPathEffect;

import android.graphics.DiscretePathEffect;

import android.graphics.Paint;

import android.graphics.Path;

import android.graphics.PathDashPathEffect;

import android.graphics.PathEffect;

import android.graphics.SumPathEffect;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

public class MainActivity extends Activity

{

@Override

protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(new MyView(this));

}

class MyView extends View

{

float phase;

PathEffect[] effects = new PathEffect[7];

int[] colors;

private Paint paint;

Path path;

public MyView(Context context)

{

super(context);

paint = new Paint();

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(4);

// 创建并初始化Path

path = new Path();

path.moveTo(0, 0);

for (int i = 1; i <= 40; i++)

{

path.lineTo(i * 20, (float) Math.random() * 60);

}

// 初始化7个颜色

colors = new int[] { Color.BLACK, Color.BLUE, Color.CYAN,

Color.GREEN, Color.MAGENTA, Color.RED, Color.YELLOW };

}

@Override

protected void onDraw(Canvas canvas)

{

canvas.drawColor(Color.WHITE);

// 不使用路径效果

effects[0] = null;

// 使用CornerPathEffect路径效果

effects[1] = new CornerPathEffect(10);

// 初始化DiscretePathEffect

effects[2] = new DiscretePathEffect(3.0f, 5.0f);

// 初始化DashPathEffect

effects[3] = new DashPathEffect(new float[] { 20, 10, 5, 10 },

phase);

// 初始化PathDashPathEffect

Path p = new Path();

p.addRect(0, 0, 8, 8, Path.Direction.CCW);

effects[4] = new PathDashPathEffect(p, 12, phase,

PathDashPathEffect.Style.ROTATE);

// 初始化ComposePathEffect

effects[5] = new ComposePathEffect(effects[2], effects[4]);

effects[6] = new SumPathEffect(effects[4], effects[3]);

// 将画布移动到(8、8)处开始绘制

canvas.translate(8, 8);

// 依次使用7种不同路径效果、7种不同的颜色来绘制路径

for (int i = 0; i < effects.length; i++)

{

paint.setPathEffect(effects[i]);

paint.setColor(colors[i]);

canvas.drawPath(path, paint);

canvas.translate(0, 60);

}

// 改变phase值,形成动画效果

phase += 1;

invalidate();

}

}

}

结果Gif

在这里插入图片描述

三、实例训练

让我们根据今天所学做两个小小的实例练习吧。

(1)手绘画板

我们主要要实现一个画板,当我们在触摸屏上移动时,就可以在屏幕上绘制任意的图案。

表面上看起来我们可以在画板上自由地画画包括直、曲线,实际上我们还是利用Canvas的drawLine()方法画直线线。当我们在画板上移动时,两次拖动时间发生点的距离很小,我们用多条极短的直线将他们连起来就好像我们画的是曲线。主要我们还是借助Android提供的Path类。

关键代码如下:

View代码:

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Path;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

public class DrawView extends View

{

// 定义记录前一个拖动事件发生点的坐标

float preX;

float preY;

private Path path;

public Paint paint = null;

// 定义一个内存中的图片,该图片将作为缓冲区

Bitmap cacheBitmap = null;

// 定义cacheBitmap上的Canvas对象

Canvas cacheCanvas = null;

public DrawView(Context context, int width , int height)

{

super(context);

// 创建一个与该View相同大小的缓存区

cacheBitmap = Bitmap.createBitmap(width, height,

Bitmap.Config.ARGB_8888);

cacheCanvas = new Canvas();

path = new Path();

// 设置cacheCanvas将会绘制到内存中的cacheBitmap上

cacheCanvas.setBitmap(cacheBitmap);

// 设置画笔的颜色

paint = new Paint(Paint.DITHER_FLAG);

paint.setColor(Color.RED);

// 设置画笔风格

paint.setStyle(Paint.Style.STROKE);

paint.setStrokeWidth(1);

// 反锯齿

paint.setAntiAlias(true);

paint.setDither(true);

}

@Override

public boolean onTouchEvent(MotionEvent event)

{

// 获取拖动事件的发生位置

float x = event.getX();

float y = event.getY();

switch (event.getAction())

{

case MotionEvent.ACTION_DOWN:

// 从前一个点绘制到当前点之后,把当前点定义成下次绘制的前一个点

path.moveTo(x, y);

preX = x;

preY = y;

break;

case MotionEvent.ACTION_MOVE:

// 从前一个点绘制到当前点之后,把当前点定义成下次绘制的前一个点

path.quadTo(preX, preY, x, y);

preX = x;

preY = y;

break;

case MotionEvent.ACTION_UP:

cacheCanvas.drawPath(path, paint); // ①

path.reset();

break;

}

invalidate();

// 返回true表明处理方法已经处理该事件

return true;

}

@Override

public void onDraw(Canvas canvas)

{

Paint bmpPaint = new Paint();

// 将cacheBitmap绘制到该View组件上

canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint); // ②

// 沿着path绘制

canvas.drawPath(path, paint);

}

}

颜色、大小代码:

<?xml version="1.0" encoding="utf-8"?>

<item android:id=“@+id/red”

android:title=“@string/color_red”/>

<item android:id=“@+id/green”

android:title=“@string/color_green”/>

<item android:id=“@+id/blue”

android:title=“@string/color_blue”/>

**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

更多Android高级工程师进阶学习资料

进阶学习视频

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

n1J-1713010069131)]

[外链图片转存中…(img-uGjp0zam-1713010069131)]

[外链图片转存中…(img-XBuBxXyQ-1713010069131)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

更多Android高级工程师进阶学习资料

进阶学习视频
[外链图片转存中…(img-YVhl6IqI-1713010069131)]

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-tnu3FzOs-1713010069132)]

里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 11
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio中,可以使用多种方法来处理图片。下面是一些常用的图片处理方法: 1. 使用Drawable对象:可以通过在应用中添加Drawable资源,并通过资源文件中的@drawable/file_name或Java代码中的R.drawable.file_name来访问Drawable对象。还可以使用Bitmap和BitmapFactory来创建和处理位图,然后将其包装成BitmapDrawable对象。 2. 绘图:Android应用可以动态生成图片,这就需要使用Android的绘图支持。绘图的基础是使用Canvas和Paint类,通过Canvas来绘制形状、文本和图像,通过Paint来设置绘制的样式和属性。 3. 获取Bitmap对象:如果需要获取BitmapDrawable所包装的Bitmap对象,可以使用BitmapDrawable中的getBitmap()方法来获取。 综上所述,Android Studio提供了丰富的图片处理功能,包括使用Drawable对象、绘图以及获取Bitmap对象。这些方法可以帮助开发者在Android应用中实现图片处理的各种需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Android studio图形图像处理](https://blog.csdn.net/weixin_43901698/article/details/90581993)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值