首页 > 代码库 > android 动态缩放视频

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