[原创] 改善 Firemonkey Canvas 几何绘图质量问题(移动平台)
说明:
Fiiremonkey 的跨平台能力,大家有目共睹(一码同介面跨四平台),唯独移动平台在几何绘图方面,质量始终不尽人意,我也曾试着去修正(如:修正曲线平滑问题),也曾找过第三方案(如:AggPas),但都不完美,我一直在想,移动平台有这么强的绘图能力及质量(Android & iOS),如果能直接拿来用,不是很好?为什么 Firemonkey 要自己重写?
目前网上许多针对此问题的改善方案,但多以控件形式,且需依各平台的绘图函数来绘图,或仅提供固定的几何图形控件,如果能延用现有的 TCanvas.Draw????? 绘图代码,只要加入几行代码(或编译开关),就能达到原生绘图的效果,岂不是很理想,于是开是构想这种方案的可行性,最后证实是可行的。
要先说明的是,这里提供的只是一种改善方案,而不是修正,最终还是希望能受到 EMB 官方的关注,由官方来改进这个问题。
用法及效果:
FMX 的绘图方法:
procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var Rect, DesRect: TRectF;
begin
Rect := PaintBox1.LocalRect;
Canvas.Stroke.Thickness := ;
Canvas.Stroke.Kind := TBrushKind.Solid;
Canvas.Stroke.Dash := TStrokeDash.DashDotDot; DesRect := Rect;
InflateRect(DesRect, -(Canvas.Stroke.Thickness / ), -(Canvas.Stroke.Thickness / )); // 线在区内
Canvas.FillRect(DesRect, , , AllCorners, );
Canvas.DrawRect(DesRect, , , AllCorners, );
end;
说明 | Android | iOS | Windows | macOS |
上面的代码,使用 FMX 绘图方法 (移动平台是有问题的) |
![]() |
![]() |
![]() |
![]() |
下面的代码,使用原生绘图方法 (四个平台全部相同了) |
![]() |
![]() |
|
![]() |
下面改成原生绘图方案,只要在原有絵图代码前後加入二行代码(原绘图代码不用更动):
{$i NativeDraw.inc}
uses FMX.Graphics.Native; procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var Rect, DesRect: TRectF;
begin
Rect := PaintBox1.LocalRect;
Canvas.Stroke.Thickness := 10;
Canvas.Stroke.Kind := TBrushKind.Solid;
Canvas.Stroke.Dash := TStrokeDash.DashDotDot; {$IFDEF UseNativeDraw}Canvas.NativeDraw(Rect, procedure begin {$ENDIF} // 原生绘图 by Aone DesRect := Rect;
InflateRect(DesRect, -(Canvas.Stroke.Thickness / 2), -(Canvas.Stroke.Thickness / 2)); // 线在区内
Canvas.FillRect(DesRect, 30, 30, AllCorners, 1);
Canvas.DrawRect(DesRect, 30, 30, AllCorners, 1); {$IFDEF UseNativeDraw}end);{$ENDIF} // 原生绘图 by Aone
end;
运作原理:
- 它的运作原理很简单,就是先配置一个原生的绘图区域 Bitmap,再将几何图形画在这个区域里,最后将这个区域里的内容,转回 TBitmap,再显示到 Canvas 里
- 利用 Delphi Pascal Helper 语言特性,针对 TCanvas 来做扩展,如此才能达到不改动原有的绘图代码
- 目前这个作法,相同的绘图代码,可以跨四个平台:
Android, iOS:使用原生绘图 TCanvasHelper 方法
- Windows, masOS:使用原来 TCanvas 方法(这二个平台本来就没有质量问题,所以不用重写)
我们无法触及 FMX 的最核心,只能利用这种 Bitmap 方式来变通,要知道这种方式可能带来的问题(记忆体及效能),才不致错用
- 注意:如果引用了 FMX.Graphics.Native 就必需使用下面的方式来写绘图代码,否则请不要引用:
{$i NativeDraw.inc}
uses FMX.Graphics.Native; {$IFDEF UseNativeDraw}Canvas.NativeDraw(Rect, procedure begin {$ENDIF} // 原生绘图 by Aone // 绘图代码 {$IFDEF UseNativeDraw}end);{$ENDIF} // 原生绘图 by Aone
调用原生绘图的 TCanvas 函数:(仅有下面函数有质量问题)
DrawLine | 画线 |
FillRect | 圆距区 |
DrawRect | 圆距框线 |
FillPath | 路径区 |
DrawPath | 路径框线 |
FillEllipse | 椭圆区 |
DrawEllipse | 椭圆框线 |
FillArc | 孤线区 |
DrawArc | 孤框线 |
FillPolygon | 多边形区 |
DrawPolygon | 多边形框线 |
IntersectClipRect | 相交剪裁区 |
ExcludeClipRect | 其它剪裁区 |
TBrush 涂刷 & TStrokeBrush 线刷:
- 支持所有涂刷特性,除了 Bitmap 涂色尚未支持(若有此需求,可自行修改源码,加入此特性)
- FMX 在移动平台是不支持画线加渐层涂色,使用原生绘图,已经可以轻松实现(支持 Linear 线渐层及 Radial 圆渐层效果):
原生 FMX procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
var Rect, DesRect: TRectF;
begin
Rect := PaintBox1.LocalRect;
Canvas.Stroke.Thickness := ;
Canvas.Stroke.Kind := TBrushKind.Gradient;
Canvas.Stroke.Dash := TStrokeDash.DashDotDot;
Canvas.Stroke.Gradient.Color := TAlphaColorRec.Blue;
Canvas.Stroke.Gradient.Color1 := TAlphaColorRec.Gold; {$IFDEF UseNativeDraw}Canvas.NativeDraw(Rect, procedure begin {$ENDIF} // 原生绘图 by Aone DesRect := Rect;
InflateRect(DesRect, -(Canvas.Stroke.Thickness / ), -(Canvas.Stroke.Thickness / )); // 线在区内
Canvas.FillRect(DesRect, , , AllCorners, );
Canvas.DrawRect(DesRect, , , AllCorners, ); {$IFDEF UseNativeDraw}end);{$ENDIF} // 原生绘图 by Aone
end;
已知问题:
- 真机 iOS 64bit 无法显示虚线(虚拟机没问题)
- 未完成的函数功能及特性,欢迎大家一起完善
文件下载:
- 源码:https://github.com/OneChen/FMXNativeDraw/
- Android Test apk:TestNativeDraw.apk
2017.06.22 新增 TestArc Demo(已更新到 GitHub):
参考资料:
- https://sourceforge.net/projects/dpfdelphiios/
- https://sourceforge.net/projects/alcinoe/
- https://developer.android.com/reference/android/graphics/Canvas.html
- https://developer.apple.com/reference/coregraphics
[原创] 改善 Firemonkey Canvas 几何绘图质量问题(移动平台)的更多相关文章
- HTML5 Canvas 2D绘图
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/ShiJiaqi. http://www.cnblogs.com/shijiaqi1066/p/4851774. ...
- Microsoft.VisualBasic.dll的妙用and 改善C#公共程序类库质量的10种方法
Microsoft.VisualBasic.dll的妙用(开发中肯定会用到哦) 前言 做过VB开发的都知道,有一些VB里面的好的函数在.NET里面都没有,而Microsoft.VisualBasic. ...
- 【原创】C#搭建足球赛事资料库与预测平台(6) 赔率数据表设计2
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源C#彩票数据资料库系列文章总目录:[目录]C#搭建足球赛事资料库与预测平台与彩票数据分析目录 本篇文章开始将逐步介 ...
- 【原创】C#搭建足球赛事资料库与预测平台(2) 数据库与XCode组件
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源C#彩票数据资料库系列文章总目录:[目录]C#搭建足球赛事资料库与预测平台与彩票数据分析目录 本篇文章开始将逐步 ...
- sonar+Jenkins 构建代码质量自动化分析平台
1.Sonar 介绍 Sonar 是一个用于管理代码质量的开源工具,可以分析代码中的bug和漏洞以及Code Smells,支持20多种编程语言的检测,如java,c/c++,python,php等语 ...
- html --- canvas --- javascript --- 绘图方法
Canvas元素是HTML5的一部分,允许脚本语言动态渲染位图像. 如有疑问请访问链接:http://javascript.ruanyifeng.com/htmlapi/canvas.html < ...
- H5新特性——--第三方绘图工具库 echarts(canvas)---SVG绘图
今天学习的内容 3.1:h5新特性---第三方绘图工具库 echarts(canvas) 百度 echarts;d3;two.js;.... 3.2:h5新特性---SVG绘图 3.2:h5新特性-- ...
- (第一章)改善JavaScript,编写高质量代码。
根据<编写高质量代码改善JavaScript程序的188个建议>这本书,来记录我目前所了解的建议方式. 建议1:警惕Unicode乱码 根据ECMA标准规定JavaScript语言可以使用 ...
- Opengl编程指南第二章:状态管理、几何绘图
//http://blog.csdn.net/longhuihu/article/details/7701874 1.绘图基础 清除窗口 glClearColor(0.0, 0.0, 0.0, 0.0 ...
随机推荐
- jstack来分析linux服务器上Java应用服务性能异常
使用jdk自带的jstack来分析linux服务器上应用服务性能异常: 1.top查找出哪个进程消耗的系统资源情况 [op1@jira ~]$ top top - 19:23:43 up 22 day ...
- Spring高级话题
Spring Aware 在实际项目中,你不可避免的要用到spring容器本身的功能资源,这时你的bean要意识到spring容器的存在,才能调用spring提供的资源.spring aware本来就 ...
- HTTP断点续传下载的原理
frombegintoend原文HTTP断点续传下载的原理 要实现断点续传下载文件,首先要了解断点续传的原理.断点续传其实就是在上一次下载断开的位置开始继续下载,HTTP协议中,可以在请求报文头中加入 ...
- Spring Boot启动流程详解
注:本文转自http://zhaox.github.io/java/2016/03/22/spring-boot-start-flow 环境 本文基于Spring Boot版本1.3.3, 使用了sp ...
- HAVING COUNT(*) > 1的用法和理解
HAVING COUNT(*) > 1的用法和理解 作用是保留包含多行的组. SELECT class.STUDENT_CODE FROM crm_class_schedule class GR ...
- Redis常用类型数据操作
sortedset: 添加: zadd key score1 member1 score2 member2... zad mysort 90 laosong 100 zhangsan 获得:zsco ...
- manta api
Authentication 有几个访问方法. 验证对服务的请求的主要方法是使用TLS上的HTTP签名. 在大多数情况下,您只需使用SSH私钥对HTTP Date标头的小写日期:和值进行签名; 这样做 ...
- java算法 蓝桥杯 摆花
问题描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时 ...
- C#给图片加文字水印
public class TxtWaterMark { public enum WaterPositionMode { LeftTop,//左上 LeftBottom,//左下 RightTop,// ...
- 【hdu4135】【hdu2841】【hdu1695】一类通过容斥定理求区间互质的方法
[HDU4135]Co-prime 题意 给出三个整数N,A,B.问在区间[A,B]内,与N互质的数的个数.其中N<=10^9,A,B<=10^15. 分析 容斥定理的模板题.可以通过容斥 ...