前几天做了一个人体模型的视频,要得到他的动作视频帧,这方面需求的,找了很长时间,东凑西拼,终于弄成后,就是效率有点差劲,贴代码:
首先是
AndroidManifest.xml的代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.getbitmap"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.getbitmap.MainActivity"
android:hardwareAccelerated="true"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.getbitmap.ActionVideoStartActivity"
android:label="@string/app_name" >
</activity>
</application>
</manifest>
之后是mainActivity.java
package com.example.getbitmap;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.media.ThumbnailUtils;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
/**
* 获取图片和视频的缩略图 这两个方法必须在2.2及以上版本使用,因为其中使用了ThumbnailUtils这个类
*/
public class MainActivity extends Activity implements OnClickListener {
private ImageView videoThumbnail;
private Bitmap bitmap;
private EditText startAngle;
private String startAngleString;
private EditText endAngle;
private String endAngleString;
private Button showBitmap;
//private Button getVideo;
private MediaMetadataRetriever retriever;
private ArrayList<Bitmap> bitmapList = new ArrayList<Bitmap>();
private HashMap<String, Double> timeList = new HashMap<String, Double>();
//
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
showBitmap.setOnClickListener(this);
// 得到sd卡中的视频文件
String videoPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "cbct.mp4";
// 你需要实现的代码
retriever = new MediaMetadataRetriever();
retriever.setDataSource(videoPath);
// 取得视频的长度(单位为毫秒)
String time = retriever
.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
}
public void init() {
videoThumbnail = (ImageView) findViewById(R.id.video_thumbnail);
startAngle = (EditText) findViewById(R.id.startAngle);
endAngle = (EditText) findViewById(R.id.endAngle);
showBitmap = (Button) findViewById(R.id.showBitmap);
}
@Override
public void onClick(View v) {
timeList.clear();
bitmapList.clear();
//得到起始角度
startAngleString = startAngle.getText().toString().trim();
endAngleString = endAngle.getText().toString().trim();
//若不为空
if (!startAngleString.equals("") && startAngleString != null
&& !endAngleString.equals("") && endAngleString != null) {
//转化为double
double startAngleNumber = Integer.parseInt(startAngleString);
double endAngleNumber = Integer.parseInt(endAngleString);
//根据角度得到要取帧的时间段
timeList = getTime(startAngleNumber,endAngleNumber);
if(timeList.size()!=0){
//根据角度判断要获取的的时间段
double startTime = timeList.get("startTime");
double endTime = timeList.get("endTime");
//得到取得的帧
bitmapList = getFrame(startTime,endTime);
if(bitmapList.size()!=0){
ZhenAnimation za = new ZhenAnimation(videoThumbnail, bitmapList, 180,
false);
za.play();//取得的帧开始执行
}
}else{
Toast.makeText(MainActivity.this, "该角度未能完善", 0).show();
}
}else{
Toast.makeText(MainActivity.this, "输入框不能为空", 0).show();
}
}
public HashMap<String, Double> getTime(double startAngleNumber,double endAngleNumber){
timeList.put("startTime", (startAngleNumber*(0.06)));
timeList.put("endTime", (endAngleNumber*(0.06)));
return timeList;
}
public ArrayList<Bitmap> getFrame(double startTime,double endTime) {
bitmapList.clear();
for (double i = startTime; i <= endTime; i = (i + 0.1)) {
bitmap = retriever.getFrameAtTime((long) (i * 1000 * 1000),
MediaMetadataRetriever.OPTION_CLOSEST);
bitmap = ThumbnailUtils.extractThumbnail(bitmap, 900, 600,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
bitmapList.add(bitmap);
}
return bitmapList;
}
/**
* 获取视频的缩略图 先通过ThumbnailUtils来创建一个视频的缩略图,然后再利用ThumbnailUtils来生成指定大小的缩略图。
* 如果想要的缩略图的宽和高都小于MICRO_KIND,则类型要使用MICRO_KIND作为kind的值,这样会节省内存。
*
* @param videoPath
* 视频的路径
* @param width
* 指定输出视频缩略图的宽度
* @param height
* 指定输出视频缩略图的高度度
* @param kind
* 参照MediaStore.Images.Thumbnails类中的常量MINI_KIND和MICRO_KIND。
* 其中,MINI_KIND: 512 x 384,MICRO_KIND: 96 x 96
* @return 指定大小的视频缩略图
*/
}
再就是ZhenAnimation.java
package com.example.getbitmap;
import java.util.ArrayList;
import android.graphics.Bitmap;
import android.widget.ImageView;
public class ZhenAnimation {
private ImageView imageView;
private ArrayList<Bitmap> drawableId;//要展现的图像集
private int duration;//切换的间隔时间
private Boolean isOneShot = false;//是否循环播放
private boolean isStop = false;
private int currIndex;
public ZhenAnimation(ImageView imageView, ArrayList<Bitmap> drawableId,
int duration, boolean isOneshot) {
this.imageView = imageView;
this.drawableId = drawableId;
this.duration = duration;
this.isOneShot = isOneshot;
imageView.setImageBitmap(drawableId.get(0));
}
public void play() {
isStop = false;
start(currIndex);
}
public void playFromIndex(int index) {
isStop = false;
currIndex = index;
start(currIndex);
}
public int getCurrentIndex() {
return currIndex;
}
public void stop() {
isStop = true;
}
public void reset(){
stop();
imageView.postDelayed(new Runnable() {
@Override
public void run() {
currIndex = 0;
play();
}
}, duration);
}
private void start(final int index) {
imageView.postDelayed(new Runnable() {
public void run() {
int i = drawableId.size();
imageView.setImageBitmap(drawableId.get(index));
if(!isStop){
if (index == drawableId.size() - 1) {
if (isOneShot) {
imageView.setImageBitmap(drawableId.get(index));
currIndex=0;
} else {
start(0);
}
} else {
start(index + 1);
}
}
}
}, duration);
currIndex = index;
}
}
再就是布局文件:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
android:id="@+id/startAngle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="number"
android:hint="请输入开始角度"
android:ems="10" >
</EditText>
<EditText
android:id="@+id/endAngle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="请输入结束角度"
android:inputType="number"
android:ems="10" >
</EditText>
<Button
android:id="@+id/showBitmap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="展示动画" />
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/image_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<requestFocus />
<TextView
android:id="@+id/clickTextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
android:text="视频缩略图" />
<ImageView
android:id="@+id/video_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp" />
</LinearLayout>
</LinearLayout>