android 动态缩放视频

android目前仅支持图片的等比缩放。对于视频的缩放,仅以填充黑边的覆盖的方式来显示。

如果实现一种视频的动态缩放效果,可以用两种图片的特效叠加来达到类似的效果

实现想法是 两层View,顶层取得当前视频一帧图像,底层视图resize视频的目标位置与大小,缩放顶层当前帧截图到目标位置,fade
away顶层视图显示出视频。

简单说
缩放当前帧图像,然后消掉显示目标视频。

核心代码如下


  1 public class VideoViewScale {
2
3 public static class ViewSize {
4
5 public int width;
6 public int height;
7
8 public ViewSize(int width, int height) {
9 this.width = width;
10 this.height = height;
11 }
12
13 }
14
15 private String TAG = VideoViewScale.class.getName();
16
17 private FrameLayout flVideo;
18 private SurfaceView svVideo;
19 private ScaleAnimation smallerScaleAnimation;
20 private ScaleAnimation largerScaleAnimation;
21 private Animation alphaAnimation;
22 private ImageView ivCapturedFrame;
23 private Handler handler;
24 public Activity activity;
25 private Bitmap capturedFrameBmp;
26
27 private final int SMALLER_CAPTURE_FRAME = 0;
28 private final int RESIZE_SMALLER_VIDEO_VIEW = 1;
29 private final int RESIZE_SMALLER_CAPTURE_FRAME_AND_FADE_OUT = 2;
30 private final int LARGER_CAPTURE_FRAME = 3;
31 private final int RESIZE_LARGER_CAPTURE_FRAME_AND_FADE_OUT_AND_RESIZE_LARGER_VIDEO_VIEW = 4;
32 private ViewSize iniSize;
33 private ViewSize dstSize;
34 private Rect marginRect;
35
36 public VideoViewScale(Activity a, FrameLayout fl, SurfaceView sv,
37 ViewSize iniS, ViewSize dstS, Rect marginR) {
38
39 this.flVideo = fl;
40 this.activity = a;
41 this.svVideo = sv;
42 this.iniSize = iniS;
43 this.dstSize = dstS;
44 this.marginRect = marginR;
45
46 handler = new Handler() {
47
48 @Override
49 public void handleMessage(Message msg) {
50
51 FrameLayout.LayoutParams llParams = null;
52 switch (msg.what) {
53 case SMALLER_CAPTURE_FRAME:
54
55 flVideo.removeView(ivCapturedFrame);
56 ivCapturedFrame = new ImageView(activity);
57 llParams = new FrameLayout.LayoutParams(iniSize.width,
58 iniSize.height);
59
60 if (capturedFrameBmp != null) {
61 ivCapturedFrame.setBackgroundDrawable(new BitmapDrawable(capturedFrameBmp));
62 }
63
64 flVideo.addView(ivCapturedFrame, llParams);
65
66 ivCapturedFrame.startAnimation(smallerScaleAnimation);
67
68 break;
69 case RESIZE_SMALLER_VIDEO_VIEW:
70 llParams = new FrameLayout.LayoutParams(dstSize.width,
71 dstSize.height);
72 llParams.setMargins(marginRect.left, marginRect.top,
73 marginRect.bottom, marginRect.right);
74 svVideo.setLayoutParams(llParams);
75 break;
76 case RESIZE_SMALLER_CAPTURE_FRAME_AND_FADE_OUT:
77
78 llParams = new FrameLayout.LayoutParams(dstSize.width,
79 dstSize.height);
80 llParams.setMargins(marginRect.left, marginRect.top,
81 marginRect.bottom, marginRect.right);
82 ivCapturedFrame.setLayoutParams(llParams);
83
84 ivCapturedFrame.startAnimation(alphaAnimation);
85
86 break;
87 case LARGER_CAPTURE_FRAME:
88
89 flVideo.removeView(ivCapturedFrame);
90
91 ivCapturedFrame = new ImageView(activity);
92 llParams = new FrameLayout.LayoutParams(dstSize.width,
93 dstSize.height);
94 llParams.setMargins(marginRect.left, marginRect.top,
95 marginRect.bottom, marginRect.right);
96
97 if (capturedFrameBmp != null) {
98 ivCapturedFrame.setBackgroundDrawable(
99 new BitmapDrawable(capturedFrameBmp));
100 }
101
102 flVideo.addView(ivCapturedFrame, llParams);
103 ivCapturedFrame.startAnimation(largerScaleAnimation);
104
105 break;
106 case RESIZE_LARGER_CAPTURE_FRAME_AND_FADE_OUT_AND_RESIZE_LARGER_VIDEO_VIEW:
107
108
109 llParams = new FrameLayout.LayoutParams(iniSize.width,
110 iniSize.height);
111 ivCapturedFrame.setLayoutParams(llParams);
112 ivCapturedFrame.startAnimation(alphaAnimation);
113
114 llParams = new FrameLayout.LayoutParams(iniSize.width,
115 iniSize.height);
116 if (svVideo != null)
117 svVideo.setLayoutParams(llParams);
118
119 break;
120
121 }
122
123 }
124
125 };
126
127 alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
128 alphaAnimation.setDuration(1000);
129 alphaAnimation.setFillAfter(true);
130
131 }
132
133 public void smaller(Bitmap capturedFrameBmp, int duration) {
134
135 Log.d(TAG, "smallerScale");
136
137 this.capturedFrameBmp = capturedFrameBmp;
138
139 float a = (float) (marginRect.top) / dstSize.height;
140
141 smallerScaleAnimation = new ScaleAnimation(1.0f,
142 (float) (dstSize.width) / iniSize.width, 1.0f,
143 (float) (dstSize.height) / iniSize.height,
144 Animation.RELATIVE_TO_SELF, (float) (marginRect.left)
145 / dstSize.width / (iniSize.width / dstSize.width - 1),
146 Animation.RELATIVE_TO_SELF, (float) (marginRect.top)
147 / dstSize.height
148 / (iniSize.height / dstSize.height - 1));
149 smallerScaleAnimation.setDuration(duration);
150 smallerScaleAnimation.setAnimationListener(new AnimationListener() {
151
152 @Override
153 public void onAnimationStart(Animation animation) {
154 Message msg = new Message();
155 msg.what = RESIZE_SMALLER_VIDEO_VIEW;
156 handler.sendMessageDelayed(msg, 0);
157
158 }
159
160 @Override
161 public void onAnimationEnd(Animation animation) {
162
163 Message msg = new Message();
164 msg.what = RESIZE_SMALLER_CAPTURE_FRAME_AND_FADE_OUT;
165 handler.sendMessageDelayed(msg, 0);
166 // Intent intent = new Intent();
167 // intent.setAction(ANIMATION_FINISH);
168 // Rect marginRect = new Rect(0, 0, 0, 0);
169 // resetCameraPreview(marginRect,
170 // 160, 110);
171 // activity.sendBroadcast(intent);
172
173
174 }
175
176 @Override
177 public void onAnimationRepeat(Animation animation) {
178
179 }
180 });
181
182 handler.sendEmptyMessage(SMALLER_CAPTURE_FRAME);
183 }
184
185 public void larger(Bitmap capturedFrameBmp, int duration) {
186
187 this.capturedFrameBmp = capturedFrameBmp;
188
189 largerScaleAnimation = new ScaleAnimation(1.0f, (float) (iniSize.width)
190 / dstSize.width, 1.0f, (float) (iniSize.height)
191 / dstSize.height, Animation.RELATIVE_TO_SELF,
192 (float) (marginRect.left) / dstSize.width
193 / (iniSize.width / dstSize.width - 1),
194 Animation.RELATIVE_TO_SELF, (float) (marginRect.top)
195 / dstSize.height
196 / (iniSize.height / dstSize.height - 1));
197
198 largerScaleAnimation.setDuration(duration);
199 largerScaleAnimation.setFillAfter(true);
200 largerScaleAnimation.setAnimationListener(new AnimationListener() {
201
202
203 @Override
204 public void onAnimationStart(Animation animation) {
205 }
206
207 @Override
208 public void onAnimationEnd(Animation animation) {
209 Message msg = new Message();
210 msg.what = RESIZE_LARGER_CAPTURE_FRAME_AND_FADE_OUT_AND_RESIZE_LARGER_VIDEO_VIEW;
211 handler.sendMessageDelayed(msg, 0);
212 }
213
214 @Override
215 public void onAnimationRepeat(Animation animation) {
216
217 }
218 });
219
220 handler.sendEmptyMessage(LARGER_CAPTURE_FRAME);
221
222 }
223
224 public void resetCameraPreview(Rect marginRect, int width, int height) {
225 this.marginRect = marginRect;
226 FrameLayout.LayoutParams llParams = null;
227
228 llParams = new FrameLayout.LayoutParams(width, height);
229 llParams.setMargins(marginRect.left, marginRect.top, marginRect.bottom,
230 marginRect.right);
231 svVideo.setLayoutParams(llParams);
232 Log.e("test","VideoWidth"+svVideo.getWidth()+" VideoHeight "+svVideo.getHeight());
233 }
234

示例代码  https://github.com/ZhuoxingGuo/VideoScale

android 动态缩放视频,布布扣,bubuko.com

时间: 2024-10-20 18:54:20

android 动态缩放视频的相关文章

android平台短视频技术之 视频编辑的经验分享.

提示一: 各位看官,这里分享的是视频编辑,即剪切/拼接/分离/合并/涂鸦/标记/叠加/滤镜等对视频的编辑操作.不是流媒体网络播放等功能,请注意. 提示二: 这些文字90%的为普及知识,10%为宣传我们的SDK,因为分享别人,有利自已,才是良性循环,才可以让我们持续分享,毕竟只分享,不有益很难持续下去.要养家糊口啊^_^. 提示三:我们是android视频编辑的专业团队,以下分享的文字,完全实际经验总结,每一个知识点您都可以在我们的SDK或开源的工程中验证.我们的SDK:https://githu

android 动态添加控件并实现每个子控件的点击事件

需求:我们要点击进入一家店铺,根据不同的店铺,显示不同条数的子条目 如:消毒间,洗菜间等...这些都是或多或少的,所以需要动态添加: 首先自定义View(linearLayout): package cn.qust.fang.widget; import io.vov.vitamio.MediaPlayer; import io.vov.vitamio.widget.MediaController; import io.vov.vitamio.widget.VideoView; import a

android 动态背景的实现以及SurfaceView中添加EditText控件

      首先还是一贯作风,我们先看案例: 静态图看不出来效果,如果用过此软件(扎客)的同学们都知道,她的背景会动.怎么样,是不是觉得很时尚,起码比静态的要好(个人观点).其实实现起来并 不复杂,这个如果让做游戏程序员做简直太小儿科了,这里我说明一点,其实我们做应用的也应该多少了解下游戏编程思维,起码对我们做应用有很好的帮助. 下面我简单介绍下实现方式. 实现原理:自定义一个SurfaceView控件.对之不停的onDraw,使得其背景动起来. 对于SurfaceView如果不了解的同学们麻烦

Android中直播视频技术探究之---基础知识大纲介绍

一.前言 最近各种视频直播app到处都是,各种霸屏,当然我们也是需要体验的,关于视频直播的软件这里就不介绍了,在不是技术的人来看,直播是一种潮流,是一种娱乐方式,但是作为一个高技术的,我们除了看看,更重要的是学习技术,其实Android中的视频技术没什么说的,因为网上的资料很多,但是之前的视频技术大部分都出现在了视频播放,就是主流的视频播放器,那个最重要的一个技术就是视频的编解码,这个也会在后续文章中详细介绍视频的处理技术.但是现在直播的技术是在之前的视频技术上又有了一个要求就是视频录制,现在录

Android动态加载那些事儿

基础 1.Java 类加载器 类加载器(class loader)是 Java?中的一个很重要的概念.类加载器负责加载 Java 类的字节代码到 Java 虚拟机中.本文首先详细介绍了 Java 类加载器的基本概念,包括代理模式.加载类的具体过程和线程上下文类加载器等,接着介绍如何开发自己的类加载器,最后介绍了类加载器在 Web 容器和 OSGi?中的应用. 2.反射原理 Java 提供的反射機制允許您於執行時期動態載入類別.檢視類別資訊.生成物件或操作生成的物件,要舉反射機制的一個應用實例,就

Android 动态改变组件大小

注意,你要改变组件的部分,要在XML中将其设置为warp_content.比如 你如果要改变button宽度,在xml中就要将其layout_width设置为wrap_content 在代码中动态设置宽度是通过设置设置LayoutParams来达到效果的 ImageView pictureView = (ImageView) convertView.findViewById(R.id.picture_view); ViewGroup.LayoutParams layoutParams=holde

Android动态改变布局,比如登陆弹出软键盘,登陆框上移(转载)

Android动态改变布局 http://www.cnblogs.com/angeldevil/p/3836256.html 遇到这么个需求,先看图:      其实是一个软件的登录界面,初始是第一个图的样子,当软键盘弹出后变为第二个图的样子,因为登录界面有用户名.密码.登录按钮,不这样的话软键盘弹出后会遮住登录按钮(其实之前的实现放到了ScrollView里面,监听软键盘弹出后滚动到底部,软键盘隐藏后滚动到顶部,也是可以的). 最简单的方法就是多加几个冗余的View,根据软键盘的状态隐藏不需要

Android多人视频聊天应用的开发(三)多人聊天

在上一篇<Android多人视频聊天应用的开发(二)一对一聊天>中我们学习了如何使用声网Agora SDK进行一对一的聊天,本篇主要讨论如何使用Agora SDK进行多人聊天.主要需要实现以下功能: 1.上一篇已经实现过的聊天功能 2.随着加入人数和他们的手机摄像头分辨率的变化,显示不同的UI,即所谓的"分屏" 3.点击分屏中的小窗,可以放大显示该聊天窗 分屏 根据前期技术调研,分屏显示最好的方式是采用瀑布流结合动态聊天窗实现,这样比较方便的能够适应UI的变化.所谓瀑布流,

Android实现小视频的录制和预览,界面和功能靠拢微信。

不过是看淡利益,看穿时间,推己及人. 先看一下效果图: 1,实现的功能 a)全屏幕预览录制播放. b)录制时间可定制(本实例15秒),录制按钮动画效果. c)录制完成即刻播放,可保存删除文件. d)录制按钮可以随意拖动复位. 2,可拓展的功能 a)可添加点击拍照功能. b)可添加开关闪关灯功能. c)对焦功能.(缺陷) d)可添加播放暂停功能. e)可分段录制,拼接视屏. 3,未实现的微信效果 a)录制视频时,拖动录制按钮实现焦距调整. b)视频压缩. 4,注意事项 a)本例以goole官方Ca