最近有个项目需要用到這个,因为获取视频的第一帧遇到了一个坑,所以就记录下来。
首先先获取图片
/**
* 根据指定的图像路径和大小来获取缩略图
* 此方法有两点好处:
* 1. 使用较小的内存空间,第一次获取的bitmap实际上为null,只是为了读取宽度和高度,
* 第二次读取的bitmap是根据比例压缩过的图像,第三次读取的bitmap是所要的缩略图。
* 2. 缩略图对于原图像来讲没有拉伸,这里使用了2.2版本的新工具ThumbnailUtils,使
* 用这个工具生成的图像不会被拉伸。
*
* @param imagePath 图像的路径
* @param width 指定输出图像的宽度
* @param height 指定输出图像的高度
* @return 生成的缩略图
*/
public static Bitmap getImageThumbnail(String imagePath, int width, int height) {
Bitmap bitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// 获取这个图片的宽和高,注意此处的bitmap为null
bitmap = BitmapFactory.decodeFile(imagePath, options);
options.inJustDecodeBounds = false; // 设为 false
// 计算缩放比
int h = options.outHeight;
int w = options.outWidth;
int beWidth = w / width;
int beHeight = h / height;
int be = 1;
if (beWidth < beHeight) {
be = beWidth;
} else {
be = beHeight;
}
if (be <= 0) {
be = 1;
}
options.inSampleSize = be;
// 重新读入图片,读取缩放后的bitmap,注意这次要把options.inJustDecodeBounds 设为 false
bitmap = BitmapFactory.decodeFile(imagePath, options);
// 利用ThumbnailUtils来创建缩略图,这里要指定要缩放哪个Bitmap对象
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
return bitmap;
}
第二种,因为传到平台去有角度倾斜就本地做了个处理。处理主要是获取旋转角度,旋转图片
/**
* 获取缩略图
*
* @param pathName sd卡图片路径
* @param reqWidth 图片大小
* @param reqHeight 图片大小
* @return
*/
public static Bitmap decodeSampledBitmapFromFd(String pathName,
int reqWidth, int reqHeight) {
int dragee = getExifOrientation(pathName);
Log.e("TAG", "=============" + dragee);
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(pathName, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
Bitmap src = BitmapFactory.decodeFile(pathName, options);
Bitmap bitmap = rotateBitmapByDegree(src, dragee);
return createScaleBitmap(bitmap, reqWidth, reqHeight);
}
//获取旋转
/**
* 获取旋转角度
*
* @param filepath
* @return
*/
public static int getExifOrientation(String filepath) {
int degree = 0;
ExifInterface exif = null;
try {
exif = new ExifInterface(filepath);
} catch (IOException ex) {
Loglg.d("TAG", "cannot read exif" + ex);
} catch (Exception e) {
e.printStackTrace();
}
if (exif != null) {
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
if (orientation != -1) {
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
}
}
return degree;
}
//旋转图片
/**
* 将图片按照某个角度进行旋转
*
* @param bm 需要旋转的图片
* @param degree 旋转角度
* @return 旋转后的图片
*/
public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
Bitmap returnBm = null;
// 根据旋转角度,生成旋转矩阵
Matrix matrix = new Matrix();
matrix.postRotate(degree);
try {
// 将原始图片按照旋转矩阵进行旋转,并得到新的图片
returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
} catch (OutOfMemoryError e) {
}
if (returnBm == null) {
returnBm = bm;
}
if (bm != returnBm) {
bm.recycle();
}
return returnBm;
}
//Bitmap处理
private static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
// 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响
private static Bitmap createScaleBitmap(Bitmap src, int dstWidth,
int dstHeight) {
Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
if (src != dst) { // 如果没有缩放,那么不回收
src.recycle(); // 释放Bitmap的native像素数组
}
return dst;
}
//获取视频的缩略图
/**
* 获取视频的缩略图
* 先通过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 指定大小的视频缩略图
*/
public static Bitmap getVideoThumbnail(String videoPath, int width, int height,
int kind) {
Bitmap bitmap = null;
// 获取视频的缩略图
bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
return bitmap;
}
或者是获取其第一帧
/**
* 获取第一帧
*
* @param path
*/
public static Bitmap getThumb(String path) {
MediaMetadataRetriever media = new MediaMetadataRetriever();
media.setDataSource(path);
Bitmap bitmap = media.getFrameAtTime();
return bitmap;
}
//获取音频、视频时长
/**
* 获取时长,单位是毫秒
*
* @param path
* @return
*/
public static long getDuration(String path) {
long duration = 0L;
MediaMetadataRetriever retr = new MediaMetadataRetriever();
try {
retr.setDataSource(path);
String time = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
if (!TextUtils.isEmpty(time)) {
try {
duration = Long.parseLong(time);
} catch (NumberFormatException e) {
duration = 0L;
}
}
Log.e("Tag", "=====duration====" + duration);
} catch (IllegalArgumentException e) {
duration = 0L;
}
return duration;
}
//因为本地需要把bitmap保存到本地,
/**
* 保存缩bitmap,这个方法是可以简化。
*
* @param mBitmap
*/
public static void saveMyBitmap(Bitmap mBitmap, Context context, String thumpFileName, String thumpPath) {
String urlpath = context.getExternalFilesDir(thumpFileName).getAbsoluteFile() + File.separator + thumpPath;
//CommonUtil.deleteFile(new File(urlpath));//每次保存前需要删除这个文件
if (mBitmap != null) {
try {
File f = new File(urlpath);
f.createNewFile();
FileOutputStream fOut = null;
fOut = new FileOutputStream(f);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 删除文件
*/
public static void deleteFile(File file) {
if (file.exists()) { // 判断文件是否存在
if (file.isFile()) { // 判断是否是文件
file.delete(); // delete()方法 你应该知道 是删除的意思;
} else if (file.isDirectory()) { // 否则如果它是一个目录
File files[] = file.listFiles(); // 声明目录下所有的文件 files[];
for (int i = 0; i < files.length; i++) { // 遍历目录下所有的文件
CommonUtil.deleteFile(files[i]); // 把每个文件 用这个方法进行迭代,这个CommUtil是这个deleteFile的,循环迭代删除
}
}
file.delete();
}
}
然后基本都记录到这吧。