
Github链接
画2D图形有两种方法:
Canvas实际上是封装了各种draw方法的类,调用draw方法把图形绘制到底层的Surface上,即绘制在Window上。
这个例子中构造了两个Canvas和一个Bitmap,分别调用其draw方法,先是mCanvas往Bitmap里绘制一个方块,再在onDraw方法内调用canvasdrawBitmap绘制这个方块。
思考一个问题,为什么mCanvas需要设置Bitmap?
很简单,因为它没有持有一块内存地址,自然没法绘制。来看一下draw的起点ViewRootImpl(软件绘制,不开启硬件加速下)。
这个通过mSurfacelockCanvas返回的Canvas是Viewdraw的canvas变量,所以当1,2情况时,Canvas都持有一个Bitmap,指向共享内存里的某一小块,当调用Canvasdraw方法时就能绘制出东西。但对于自定义Canvas来说并不是,即使设置一个Bitmap和绘制了Bitmap,但不往共享内存上写,屏幕上是不会显示的,SurfaceView同理,通过SurfacelockCanvas获取持有共享内存的Canvas,绘制完毕后调用SurfaceunlockCanvasAndPost把绘制内容显示到surface上并release掉Canvas。
顺带一提Canvassave和Canvasrestore方法,如下Demo
效果图如
画的是三个颜色和旋转角度都不同的小方形。
步骤1把默认坐标系旋转20°,画出第一个蓝色的方形,步骤2保存当前的matrix(旋转了20°),继续旋转20°,此时坐标系已经旋转了40°,画出第二个**的方块,步骤3,恢复上一步保存的matrix(旋转了20°),此时坐标系还是旋转了20°,步骤4,再旋转40°,此时坐标系旋转了60°,画出第三个黑色方块。
Canvassave用于保存当前matrix和clip,Canvasrestore用于恢复上次保存的matrix和clip。
Drawable是一个能画出来的物体的抽象,使用前需要调用setBounds确定位置和大小,通过getIntrinsicHeight和getIntrinsicWidth取到实际大小。Drawable可以有几种形式存在:Bitmap、Nine Patch、Vector、Shape、Layers等。
从ResourcegetDrawable会判断是否xml结尾,不是的话走6,7步,如果从xml中读取,需要getResourcegetDrawable -> ResourceImplloadDrawableForCookie -> drawablecreateFromXml -> DrawableInflaterinflateFromXmlForDensity -> drawableinflateFromTag
看一下Shape实现类GradientDrawable的inflate实现,读取各项属性并赋值,到draw方法。
调用canvasdrawRect把mRect画出来,而mRect的赋值在ensureValidRect。[上传失败(image-a25af0-1515826613001)]
bounds在哪里设置的?答案是ImageViewupdateDrawable内,会调用DrawablegetIntrinsicHeight赋值(从xml中size属性读取),再调用configureBounds -> setBounds,如果使用的不是ImageView,一定要在draw之前 调用setBounds ,否则size就会出错。
回到loadDrawableForCookie,再看一下6,7步加载的过程,通过AssetManager读取流数据,通过DrawablecreateFromResourceStream这个我们经常使用的方法获取到Drawable。
取到屏幕密度之后调用BitmapFactorydecodeResourcesStream,计算密度后调用native创建Bitmap,感兴趣的同学可以看下更具体的分析文章(如 理解Bitmap )。
本文探究了两点
Android 711 源码
Android 官方文档, Canvas and Drawable , Drawable 等
如果是三星手机中保存的在相册中找不到,建议:
1重启手机,打开相册查看。
2退出相册,重新进入查看。
3设定--应用程序--相册--设置为默认--清除默认值(设定--应用程序管理器--全部--相册--清除默认值。)
4若相册照片存储在内存卡里,换其他内存卡。
5将数据备份(联系人,短信,等),恢复出厂设置
若问题依然存在,建议携带上购机发票、包修卡和手机送到当地的售后服务中心,由专业的工程师帮助检测。
canvas画布保存为:
function convertCanvasToImage(canvas) {var image = new Image();
imagesrc = canvastoDataURL("image/png");
return image;
canvas参数为你的canvas对象,返回一个对象,你可以将这个image放到网页结构中,如果要保存图像,可以将canvastoDataURL("image/png")返回的base64格式的数据放到input(type=hidden)中,用户点击上传按钮(或设置表单自动提交),将base64格式的数据上传
形如:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABbSURBVDhPY8AFMvJL/oMwlEs8yMgvJVcjyMbSYaERogCC0/OAGIkPwaVQMUhgQWiggWANIAzUhKoBpgjdMIhBUHsxAdxkUgHMBiiXeDAQNkICAsolHuC3kYEBAG/wdxC2W2tUAAAAAElFTkSuQmCC
服务器端接收到字符串(以上字符串可以直接在浏览器中打开,IE低版本就算了,能用canvas的浏览器都可以)后根据data:image/png得知应该保存的文件类型扩展名(png),然后将base64,后面的base64编码字符串解码(后端语言实现,如PHP用base64_decode()函数),将解码后的二进制数据以二进制的形式保存到服务器上(形式)
如果存数据库,可以直接存base64编码,读取时候解码也行,建议以文件形式存储,数据库不适合存大文件
var video = documentgetElementById("videoElement"); //获取前台要截图的video对象
videosetAttribute('crossOrigin', 'anonymous') // 跨域处理
var canvas = windowcanvas = documentcreateElement("canvas");
canvaswidth = 500;
canvasheight = 300;
canvasgetContext('2d')drawImage(video, 0, 0,500,500); // 将当前视频渲染在画布上,大小和视频分辨率一致
var images = canvastoDataURL("image/png"); //canvas的api中的toDataURL()保存图像[toDataUrl](>
以上就是关于Android绘图基础--Canvas和Drawable全部的内容,包括:Android绘图基础--Canvas和Drawable、为什么手机app canvas 导入通道照片不成功手机相册里是带通道的,上传到app里就是有白边、html5 canvas在线生成图片后怎么样保存到数据库(服务器端)而不是本地等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)