Android开发之视频监控区域报警设定
来源:互联网 发布:windows ce模拟器 编辑:程序博客网 时间:2024/05/22 10:43
最近接到一个来自产品的需求如下:用手在视频画框内画矩形框,矩形框内有物体移动将进行报警,最多三个区域
刚接到需求脑海瞬间行成了一个解决方案,这得益于我之前对github开源项目的“见多识广”!有事没事多看看一些优秀的开源项目还是很有用的。(每次只能选一个区域上传到服务器,根据次数控制是否支持再次选取)
首先呢感谢开源项目:https://github.com/edmodo/cropper
我需要如何修改呢?暂且分为以下几个步骤:
获取服务器端原图
根据服务器的宽高比例设定ImageView的宽高
修改开源库矩形框样式级是否隐藏选取框
提供获取矩形四个点的比例值,用于回传到服务器
首先明确一点,服务器的图片按照16:9的约定(16:9的比例我这里是写死的,还可以新增自定义属性来控制),图片的宽高一定大于手机的控件宽高,所以我们需要获取屏幕宽度,按照与服务器约定比例16:9动态设置view宽度(onLayout函数内调用,以防屏幕旋转问题)
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); int width = wm.getDefaultDisplay().getWidth(); int height = width/16*9; setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height)); super.onLayout(changed, left, top, right, bottom); mBitmapRect = getBitmapRect(); initCropWindow(mBitmapRect); }
注意: layoutParmas,這里针对的是我自己项目内父控件编码,如有需要自行修改别完全copy(可以改为通用getLayoutParams..)
如何能保证服务器获取的原图能完全显示到控件里面呢?这里需要使用到ImageView的缩放类型centerInside,如果你还不完全了解scaleType,可以参考下面内容(了解的略过)
内容摘自:
http://blog.csdn.net/hhbgk/article/details/8101676
CENTER /center 按图片的原来size居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示
CENTER_CROP / centerCrop 按比例扩大图片的size居中显示,使得图片长(宽)等于或大于View的长(宽)
CENTER_INSIDE / centerInside 将图片的内容完整居中显示,通过按比例缩小或原来的size使得图片长/宽等于或小于View的长/宽
FIT_CENTER / fitCenter 把图片按比例扩大/缩小到View的宽度,居中显示
FIT_END / fitEnd 把图片按比例扩大/缩小到View的宽度,显示在View的下部分位置
FIT_START / fitStart 把图片按比例扩大/缩小到View的宽度,显示在View的上部分位置
FIT_XY / fitXY 把图片不按比例扩大/缩小到View的大小显示
MATRIX / matrix 用矩阵来绘制,动态缩小放大图片来显示。
修改代码如下
public PrecinctImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); setScaleType(ScaleType.CENTER_INSIDE); }
由于需求有限制选取区域三次,所以新增属性isOpenPrecinct,去掉原有所有自定义属性(都用不到干掉吧,强迫症患者没办法),自定义属性解析后在onDraw 函数做一个开关作用
<declare-styleable name="PrecinctImageView"> <attr name="isOpenPrecinct" format="boolean"/> </declare-styleable> @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(isOpenPrecinct){ drawDarkenedSurroundingArea(canvas); drawBorder(canvas); drawCorners(canvas); } }
去掉原有的draw网格线方法,修改四个角的绘制,改为drawCircle
private void drawCorners(@NonNull Canvas canvas) { final float left = Edge.LEFT.getCoordinate(); final float top = Edge.TOP.getCoordinate(); final float right = Edge.RIGHT.getCoordinate(); final float bottom = Edge.BOTTOM.getCoordinate(); final float lateralOffset = (mCornerThickness - mBorderThickness) / 2f; final float startOffset = mCornerThickness - (mBorderThickness / 2f); canvas.drawCircle(left, top, radioSize, mCornerPaint); canvas.drawCircle(right, top, radioSize, mCornerPaint); canvas.drawCircle(left, bottom, radioSize, mCornerPaint); canvas.drawCircle(right, bottom, radioSize, mCornerPaint); }
修改边框圆点样式,通过修改value 下默认值实现
<?xml version="1.0" encoding="utf-8"?><resources> <color name="white_translucent">#AAFFFFFF</color> <color name="black_translucent">#B0000000</color> <color name="border">#FFB529</color> <color name="guideline">@color/white_translucent</color> <color name="corner">#FFB529</color> <color name="surrounding_area">#66000000</color></resources><?xml version="1.0" encoding="utf-8"?><resources> <dimen name="border_thickness">1dp</dimen> <dimen name="corner_thickness">5dp</dimen> <dimen name="guideline_thickness">1px</dimen> <dimen name="target_radius">24dp</dimen> <dimen name="snap_radius">3dp</dimen> <dimen name="corner_length">20dp</dimen></resources>
最后一步获取四个点坐标,根据控件的宽高转换为比例值,阅读源码发现Edge类可以为我们直接获取点坐标
public PointP getPrecinctPointP(){ PointP pointP = new PointP(); pointP.setLeftTopX(Edge.LEFT.getCoordinate()/getMeasuredWidth()); pointP.setLeftTopY(Edge.TOP.getCoordinate() / getMeasuredHeight()); pointP.setRightTopX(Edge.RIGHT.getCoordinate() / getMeasuredWidth()); pointP.setRightTopY(Edge.TOP.getCoordinate() / getMeasuredHeight()); pointP.setLeftBottomX(Edge.LEFT.getCoordinate() / getMeasuredWidth()); pointP.setLeftBottomY(Edge.BOTTOM.getCoordinate() / getMeasuredHeight()); pointP.setRightBottomX(Edge.RIGHT.getCoordinate() / getMeasuredWidth()); pointP.setRightBottomY(Edge.BOTTOM.getCoordinate()/getMeasuredHeight()); return pointP; }
以上修改看上去没有任何问题,但是结果呢总是那么不如人愿!这个开源库getBitmapRect()函数
private RectF getBitmapRect() { final Drawable drawable = getDrawable(); if (drawable == null) { return new RectF(); } //*************略************ }
这里获取的src对应的drawable资源,而在某种情况下图片如果比控件宽高小,设置src会导致图片显示不能完全覆盖控件,部分显示纯黑色,如果此时设置为Background,源码里getBitmapRect()获取到的范围值为0,所以这里应该修改代码如下
private RectF getBitmapRect() { final Drawable drawable = getBackground(); if (drawable == null) { return new RectF(); }<idea.analyzesystem.precinct.PrecinctImageView android:id="@+id/precinctImageView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/content_padding" android:adjustViewBounds="true" android:background="@drawable/butterfly"/>
最后附上效果图:
- Android开发之视频监控区域报警设定
- GB28181 SIP视频监控系列之 报警事件流程
- zabbix监控之短信报警
- 监控--nagios之 邮件报警(三)
- 数模混合监控,视频如何联动报警、消防、门禁?
- 视频监控开发文档
- 视频监控开发
- 视频监控之VSCloud
- 视频监控之 Gstreamer
- Android视频监控方案
- Android开发之视频播放
- Android开发之视频录制
- Android开发之录制视频
- Android开发之播放视频
- Android开发之视频播放
- 手机视频开发,视频监控开发
- Android 开发之Google Tag Manager 网络设定
- 网站运维之道 监控与报警机制
- 浅谈Callable接口
- ggplot2
- Linux查看版本等命令
- Codeforces
- LIVE555再学习 -- testRTSPClient 源码分析
- Android开发之视频监控区域报警设定
- Unsolved Program
- 泰国自由行攻略 起航篇
- 为什么LoRa可以在能源计量领域快速突破?
- 机器学习之支持向量机(六)
- java List的遍历和自定义排序
- 二叉树遍历
- javascript深拷贝的实现
- 贝塞尔曲线收录:四,使用UIBezierPath和CAShapeLayer画各种图形