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