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
时间: 2024-10-20 18:54:20