概述
目前大部分智能手机拍照效果好,图片像素很高.但是在存储或传输图片的时候不太方便,需要首先将其进行压缩.
先看看效果图.
注意,最后一张图片显示的压缩前后两张图似乎没有太大区别,但事实上压缩前图片为1.6MB,压缩后只有141KB.(如有需要可以根据源代码自己对压缩后图片大小进行调整,我这里设置的是压缩后图片大小不超过200KB.压缩后的图片会保存在SD卡的PicCompress文件夹下)
完整的源代码以及下载链接我会在后面给出下载链接,下面我对程序用到的几个重要的函数进行简单说明.
首先是图片压缩函数.这里给出了两个压缩函数(两种方式的输入不一样,大家可以根据自己的需要进行选择),第一个函数是compressImage(String path, int size)
/**
* 压缩图片。
* @param path 图片路径
* @param size 压缩后图片最大尺寸(单位:KB)
* @return 压缩后的图片
* @throws IOException
*/
public static Bitmap compressImage(String path, int size)
throws IOException {
Bitmap bitmap = null;
// 取得图片
InputStream is = new FileInputStream(path);
BitmapFactory.Options options = new BitmapFactory.Options();
// 这个参数代表,不为bitmap分配内存空间,只记录一些该图片的信息(例如图片大小),说白了就是为了内存优化
options.inJustDecodeBounds = true;
// 通过创建图片的方式,取得options的内容(这里就是利用了java的地址传递来赋值)
BitmapFactory.decodeStream(is, null, options);
// 关闭流
is.close();
// // 生成压缩的图片
int i = 0;
while (true) {
// 这一步是根据要设置的大小,使宽和高都能满足
if ((options.outWidth >> i <= size)
&& (options.outHeight >> i <= size)) {
// 重新取得流,注意:这里一定要再次加载,不能二次使用之前的流!
is = new FileInputStream(path);
// 这个参数表示 新生成的图片为原始图片的几分之一。
options.inSampleSize = (int) Math.pow(2.0D, i);
// 这里之前设置为了true,所以要改为false,否则就创建不出图片
options.inJustDecodeBounds = false;
options.inPreferredConfig = Config.ARGB_8888;
// 同时设置才会有效
options.inPurgeable = true;
// 当系统内存不够时候图片自动被回收
options.inInputShareable = true;
// 创建Bitmap
bitmap = BitmapFactory.decodeStream(is, null, options);
break;
}
i += 1;
}
return bitmap;
}
第二个函数是imageZoom(Bitmap bm, double maxSize)(最后选用的是这种方法)
/**
* 缩放图片到固定文件大小
* @param bm 需要缩放的图片
* @param maxSize 目标文件大小,单位:KB
* @return
*/
public static Bitmap imageZoom(Bitmap bm, double maxSize) {
// 图片允许最大空间 单位:KB
// 将bitmap放至数组中,意在bitmap的大小(与实际读取的原文件要大)
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] b = baos.toByteArray();
// 将字节换成KB
double mid = b.length / 1024;
// 判断bitmap占用空间是否大于允许最大空间 如果大于则压缩 小于则不压缩
if (mid > maxSize) {
// 获取bitmap大小 是允许最大大小的多少倍
double i = mid / maxSize;
// 开始压缩 此处用到平方根 将宽带和高度压缩掉对应的平方根倍
// 保持刻度和高度和原bitmap比率一致,压缩后也达到了最大大小占用空间的大小
bm = zoomImage(bm, bm.getWidth() / Math.sqrt(i), bm.getHeight()
/ Math.sqrt(i));
}
return bm;
}
/***
* 图片的缩放方法
*
* @param bgimage
* :源图片资源
* @param newWidth
* :缩放后宽度
* @param newHeight
* :缩放后高度
* @return
*/
public static Bitmap zoomImage(Bitmap bgimage, double newWidth,
double newHeight) {
// 获取这个图片的宽和高
float width = bgimage.getWidth();
float height = bgimage.getHeight();
// 创建操作图片用的matrix对象
Matrix matrix = new Matrix();
// 计算宽高缩放率
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 缩放图片动作
matrix.postScale(scaleWidth, scaleHeight);
Bitmap bitmap = Bitmap.createBitmap(bgimage, 0, 0, (int) width,
(int) height, matrix, true);
return bitmap;
}
还有一个重要的函数就是将Bitmap保存成图片的函数.本应用将系统时间设为图片名.最后要注意保存后通过广播对相册进行通知.
public static void saveImageToGallery(Context context, Bitmap bmp) {
// 首先保存图片
File appDir = new File(Environment.getExternalStorageDirectory(), "PicCompress");
if (!appDir.exists()) {
appDir.mkdir();
}
Log.d("PICCOMPRESS","文件夹创建成功!");
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
bmp.compress(CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 其次把文件插入到系统图库
try {
MediaStore.Images.Media.insertImage(context.getContentResolver(),
file.getAbsolutePath(), fileName, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 最后通知图库更新
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" +file.getAbsolutePath())));
Log.d("PICCOMPRESS","广播通知相册成功!");
}
除此之外PopupWindow的使用也比较重要.PopupWindow整体比较美观,这里使用它就是让用户选择拍照获取图片还是直接从相册选取图片.初始化PopupWindow的方法如下:
private void initPopWIndow(){
popupWindow=new PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
View view= LayoutInflater.from(context).inflate(R.layout.popwindow_select_photo,null);
TextView selectPhoto=(TextView)view.findViewById(R.id.selectPhoto);
selectPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Pick any photo"), RESUEST_SELECT_PHOTO);
}
});
TextView takePhoto=(TextView)view.findViewById(R.id.takePhoto);
takePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
photoFile = bitMapIO.getFullFile();
//polygonBean.setFileName(photoFile.toString());
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
imageUri = Uri.fromFile(photoFile);
startActivityForResult(intent, RESUEST_PHOTO);
}
});
TextView cancel=(TextView)view.findViewById(R.id.cancel);
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
}
});
popupWindow.setContentView(view);
popupWindow.setFocusable(true);
popupWindow.setOutsideTouchable(true);
ColorDrawable colorDrawable = new ColorDrawable(Color.BLUE);
popupWindow.setBackgroundDrawable(colorDrawable);
}
其他部分,比如布局文件什么的大家直接看源代码就好.注意要添加几项权限:
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
下面是源代码的下载链接:点击这里
最后
以上就是能干菠萝为你收集整理的Android图片压缩(包含拍照或从相册选取图片,PopupWindow的使用)的全部内容,希望文章能够帮你解决Android图片压缩(包含拍照或从相册选取图片,PopupWindow的使用)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复