自定义ImageView系列 - 区域截图(上)

功能要点:

  1. 根据控件自身大小计算合适的透明正方形预览区;
  2. 截取预览区图像并按照指定的尺寸缩放,生成Bitmap对象。
    本文着重介绍上述第1个要点。

博主又来更新文章啦!
关于ImageView呢,其实我之前接触过一些继承它来实现一些功能。比如双指缩放,单指移动之类。而最近工作中又要用到继承它来实现某些功能。借此机会好好整理一下,也分享给更多需要的朋友们!
使用本系列文章完成的自定义多功能ImageView可以实现微信中的头像选择的照片调整功能。而且,微信的图片调整界面会有不流畅的情况出现。而用本文中的办法是不会出现卡顿现象的。当然,这可能是机器的原因,不同的机器可能表现不同。我使用的测试机是三星的S6。
废话不多说,我们来讲一下如何绘制中间的透明框。
思路是这样的:为了更好的可移植性,首先通过获取ImageView的尺寸,获得ImageView的尺寸;然后通过该尺寸计算出控件中点和合适的正方形边长,一般是由宽和高其中最短的一者决定的;最后,将该正方形外的所有部分给一个半透明的黑色,再画出正方形的边缘即可。
获取控件的高度不是难事,继承了ImageView后,调用getWidth()和getHeight()方法即可完成宽高的获取。
获取控件的中点的方法是首先获取控件所在位置的起始点,也就是左上角的x和y的绝对像素坐标点。然后与宽度和高度分别相加,就可得到控件的终止点,也就是控件右下角的x和y的绝对像素坐标点。有了这两个值,控件的中点就可以确定下来了。
下面再定义预览框的边长。由于这里我们要采用绝对像素值,因此需要根据控件的大小动态计算出预览框的大小。这里我要提醒各位的就是:一个正方形,只要有两个完整的x和y轴的组合坐标,就可以确定该正方形的位置了,即对角坐标。我们这里计算左上和右下的位置。
左上角x坐标我是采用了中点x坐标减控件起点x位置再除以8确定的。换言之,就是该值是整个预览框距离左边的距离,而又由于这是一个正方形,因此右上角的坐标也就同时确定了(中点坐标x减去左上角x坐标再乘以2)。y轴坐标也很容易了,只需用中点y坐标减去上述两个x轴坐标之差的二分之一就可以了。由此,y轴终点的坐标也可以计算出来了,即用起点y轴坐标加上两个x轴之差坐标即可。
特别注意 - 这里有坑
后面我会把这部分的代码贴上,个人私心想,肯定会有人直接复制粘贴,所以……必须提醒一下各位:犹豫项目需求问题,我这里只考虑了控件高度大于控件宽度的情况,所以,诸位在复制粘贴后,务必判断一下宽高的情况,然后分情况讨论。
上述问题分别出现在中点和预览区边距的计算上。
如果这个坑的问题没看懂,没事,试一次就知道了。方法是:不要限制屏幕旋转,然后整个屏幕放这样一个ImageView,然后倒转屏幕,看看正方形会发生什么变化。
祝君好运!
最后,我们画正方形的边缘,再在其余的部分给定半透明黑色即可。这里就直接放代码片段了:
画正方形边缘:

if (previewEdge != null) {
//上
canvas.drawLine(previewEdge[0], previewEdge[2], previewEdge[1], previewEdge[2], rectPaint);
//左
canvas.drawLine(previewEdge[0], previewEdge[2], previewEdge[0], previewEdge[3], rectPaint);
//下
canvas.drawLine(previewEdge[0], previewEdge[3], previewEdge[1], previewEdge[3], rectPaint);
//右
canvas.drawLine(previewEdge[1], previewEdge[2], previewEdge[1], previewEdge[3], rectPaint);

解释一下:该部分代码放在重写的onDraw()中。previewEdge是一个有4个int值的数组,分别代表左上和右下的x和y坐标值。稍后贴出计算部分代码。
填充半透明黑色:

//灰色部分
canvas.drawRect(0, 0, previewEdge[0], myLocationEnd[1], rectBgPaint);
canvas.drawRect(previewEdge[0], 0, previewEdge[1], previewEdge[2], rectBgPaint);
canvas.drawRect(previewEdge[1], 0, myLocationEnd[0], myLocationEnd[1], rectBgPaint);
canvas.drawRect(previewEdge[0], previewEdge[3], previewEdge[1], myLocationEnd[1], rectBgPaint);

各种计算的代码片:

//获取控件自身起始点
myLocationStart = new int[2];
getLocationOnScreen(myLocationStart);
//获取控件自身终止点
myLocationEnd = new int[2];
myLocationEnd[0] = getWidth() + myLocationStart[0];
myLocationEnd[1] = getHeight() + myLocationStart[1];
//计算控件自身中点
myLocationMid = new int[2];
myLocationMid[0] = (myLocationStart[0] + myLocationEnd[0]) / 2;
myLocationMid[1] = (myLocationStart[1] + myLocationEnd[1]) / 2 - myLocationStart[1];
//设置中间预览框边框色
rectPaint = new Paint();
rectPaint.setColor(Color.WHITE);
rectPaint.setStrokeWidth(2);
rectBgPaint = new Paint();
rectBgPaint.setColor(getResources().getColor(R.color.photo_adjust_for_avator_bg));
//计算中间预览边框位置
previewEdge = new int[4];
previewEdge[0] = (myLocationMid[0] - myLocationStart[0]) / 8;
previewEdge[1] = myLocationEnd[0] - previewEdge[0];
previewEdge[2] = myLocationMid[1] - ((previewEdge[1] - previewEdge[0]) / 2);
previewEdge[3] = myLocationMid[1] + ((previewEdge[1] - previewEdge[0]) / 2);

变量的名字都很容易看懂吧,我这里就不详述了。
最后说一句,这个最好自己练习一下计算,印象深一些。完整的ImageView类代码将在整个系列文章的最后一篇中贴出。希望大家多多支持,谢谢!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容