Android 高级绘图

举报
ShaderJoy 发表于 2021/12/30 01:00:44 2021/12/30
【摘要】 我们已经介绍了Canvas,在那里,已经学习了如何创建自己的View。在第7章中也使用了Canvas来为MapView标注覆盖。 画布(Canvas)是图形编程中一个很普通的概念,通常由三个基本的绘图组件组成: Canvas 提供了绘图方法,可以向底层的位图绘制基本图形。 Paint 也称为" 刷子",Paint可以指...






刷子








可以画什么?

























从Paint中完成工作


笔刷和调色板 对象的轮廓










使用透明度




  
  1. // 使用红色,并让它50%透明
  2. int opacity = 127;
  3. int intColor = Color.argb(opacity, 255, 0, 0);
  4. int parsedColor = Color.parseColor("#7FFF0000");

或者,也可以使用setAlpha方法来设置已存在的Paint对象的透明度:


  
  1. // 让颜色50%透明
  2. int opacity = 127;
  3. myPaint.setAlpha(opacity);




Shader介绍





LinearGradient RadialGradient SweepGradient


它可以创建多个Shader和BitmapShader的组合




  
  1. Paint shaderPaint = new Paint();
  2. shaderPaint.setShader(myLinearGradient);



定义渐变Shader



  
  1. int colorFrom = Color.BLACK;
  2. int colorTo = Color.WHITE; LinearGradient linearGradientShader = new LinearGradient(x1, y1, x2, y2, colorFrom, colorTo, TileMode.CLAMP)



  
  1. int[] gradientColors = new int[3];
  2. gradientColors[0] = Color.GREEN;
  3. gradientColors[1] = Color.YELLOW;
  4. gradientColors[2] = Color.RED;
  5. float[] gradientPositions = new float[3];
  6. gradientPositions[0] = 0.0f;
  7. gradientPositions[1] = 0.5f;
  8. gradientPositions[2] = 1.0f;
  9. RadialGradient radialGradientShader=new RadialGradient(centerX,centerY, radius, gradientColors, gradientPositions, TileMode.CLAMP);

使用Shader TileModes




CLAMP 

使用Shader的边界颜色来填充剩余的空间。

MIRROR 

在水平和垂直方向上拉伸Shader图像,这样每一个图像就都能与上一个缝合了。

REPEAT 

在水平和垂直方向上重复Shader图像,但不拉伸它。



使用MaskFilter





BlurMaskFilter 

指定了一个模糊的样式和半径来处理Paint的边缘。

EmbossMaskFilter 

指定了光源的方向和环境光强度来添加浮雕效果。




  
  1. // 设置光源的方向
  2. float[] direction = new float[]{ 1, 1, 1 };
  3. //设置环境光亮度
  4. float light = 0.4f;
  5. // 选择要应用的反射等级
  6. float specular = 6;
  7. // 向mask应用一定级别的模糊
  8. float blur = 3.5f;
  9. EmbossMaskFilter emboss=new EmbossMaskFilter(direction,light,specular,blur);
  10. // 应用mask myPaint.setMaskFilter(emboss);




使用ColorFilter







ColorMatrixColorFilter 

可以指定一个4×5的ColorMatrix并将其应用到一个Paint中。ColorMatrixes通常在程序中用于对图像进行处理,而且由于它们支持使用矩阵相乘的方法来执行链接转换,所以它们很有用。


LightingColorFilter 

乘以第一个颜色的RGB通道,然后加上第二个颜色。每一次转换的结果都限制在0到255之间。

PorterDuffColorFilter 

可以使用数字图像合成的16条Porter-Duff 规则中的任意一条来向Paint应用一个指定的颜色。







使用PathEffect






CornerPathEffect

可以使用圆角来代替尖锐的角从而对基本图形的形状尖锐的边角进行平滑。


DashPathEffect 

可以使用DashPathEffect来创建一个虚线的轮廓(短横线/小圆点),而不是使用实线。你还可以指定任意的虚/实线段的重复模式。


DiscretePathEffect

与DashPathEffect相似,但是添加了随机性。当绘制它的时候,需要指定每一段的长度和与原始路径的偏离度。


PathDashPathEffect 

这种效果可以定义一个新的形状(路径)并将其用作原始路径的轮廓标记。



SumPathEffect 

顺序地在一条路径中添加两种效果,这样每一种效果都可以应用到原始路径中,而且两种结果可以结合起来。


ComposePathEffect 

将两种效果组合起来应用,先使用第一种效果,然后在这种效果的基础上应用第二种效果。



borderPaint.setPathEffect(new CornerPathEffect(5));
 



修改Xfermode






AvoidXfermod

指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。

PixelXorXfermode

当覆盖已有的颜色时,应用一个简单的像素XOR操作。

PorterDuffXfermode 

这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。




AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID); borderPen.setXfermode(avoid);
 


使用抗锯齿效果提高Paint质量







  
  1. myPaint.setSubpixelText(true);
  2. myPaint.setAntiAlias(true);

2D图形的硬件加速







myActivity.requestWindowFeature(Window.FEATURE_OPENGL)
 






Canvas绘图最佳实践经验








考虑硬件加速 

OpenGL硬件加速对2D图形的支持是非常好的,所以你总是应该考虑它是否适合你的活动。另一种比较优秀的方法是只用一个单独的View和迅速的、耗时的更新来组成活动。一定要保证你使用的基本图形能够被硬件支持。


考虑大小和方向 

当在设计View和布局的时候,一定要保证考虑(和测试)它们在不同的分辨率和大小下的外观。


只创建一次静态对象 

在Android中对象的创建是相当昂贵的。因此,在可能的地方,应用只创建一次像Paint对象、Path和Shader这样的绘图对象,而不是在View每次无效的时候都重新创建它们。


记住onDraw是很消耗资源的 

执行onDraw方法是很消耗资源的处理,它会强制Android执行多个图片组合和位图构建操作。下面有几点建议可以让你修改Canvas的外观,而不用重新绘制它:


使用Canvas转换 

可以使用像rotate和translate这样的转换,来简化Canvas中元素复杂的相关位置。例如,相比放置和旋转一个表盘周围的每一个文本元素,你可以简单地将canvas旋转22.5?,然后在相同的位置绘制文本。


使用动画 

可以考虑使用动画来执行View的预设置的转换,而不是手动地重新绘制它。在活动的View中可以执行缩放、旋转和转换动画,并可以提供一种能够有效利用资源的方式来提供缩放、旋转或者抖动效果。


考虑使用位图和9 Patch

如果View使用了静态背景,那么你应该考虑使用一个图片,如位图或者9 patch,而不是手动地重新绘制。




文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。

原文链接:panda1234lee.blog.csdn.net/article/details/8564058

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。