自己写的图片压缩上传
void takpic(){
findViewById(R.id.yh_img).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*
//加距离限制
if(xzds>XZ)//限制距离为1KM
{
Toast.makeText(YhpaPostActivity.this,"离线路距离太远!,当前距离线路最近点为:"+xzds+"km",Toast.LENGTH_SHORT).show();
return;
}
*/
//只有创建人才可以访问相册
new AlertDialog.Builder(GjAddActivity.this)
.setIcon(R.mipmap.picture)
.setMessage("插入图片")
.setPositiveButton("拍照", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
checkPermissionAndCamera();
}
}).setNegativeButton("相册", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
chooseFromAlbum();
}
}).create().show();
}
});
}
/**
* 检查权限并拍照。
* 调用相机前先检查权限。
*/
private void checkPermissionAndCamera() {
int hasCameraPermission = ContextCompat.checkSelfPermission(getApplication(),
Manifest.permission.CAMERA);
if (hasCameraPermission == PackageManager.PERMISSION_GRANTED) {
//有调起相机拍照。
openCamera();
} else {
//没有权限,申请权限。
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},
PERMISSION_CAMERA_REQUEST_CODE);
}
}
/**
* 处理权限申请的回调。
*/
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == PERMISSION_CAMERA_REQUEST_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//允许权限,有调起相机拍照。
openCamera();
} else {
//拒绝权限,弹出提示框。
Toast.makeText(this,"拍照权限被拒绝",Toast.LENGTH_LONG).show();
}
}
}
/**
* 调起相机拍照
*/
private void openCamera() {
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 判断是否有相机captureIntent.resolveActivity(getPackageManager()) != null
if (true) {//true
File photoFile = null;
Uri photoUri = null;
if (isAndroidQ) {
// 适配android 10
photoUri = createImageUri();
} else {
try {
photoFile = createImageFile();
photoFilet = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
mCameraImagePath = photoFile.getAbsolutePath();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri
photoUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", photoFile);
} else {
photoUri = Uri.fromFile(photoFile);
}
}
}
mCameraUri = photoUri;
if (photoUri != null) {
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
captureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(captureIntent, CAMERA_REQUEST_CODE);
}
}
}
/**
* 创建图片地址uri,用于保存拍照后的照片 Android 10以后使用这种方法
*/
private Uri createImageUri() {
String status = Environment.getExternalStorageState();
// 判断是否有SD卡,优先使用SD卡存储,当没有SD卡时使用手机存储
if (status.equals(Environment.MEDIA_MOUNTED)) {
return getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
} else {
return getContentResolver().insert(MediaStore.Images.Media.INTERNAL_CONTENT_URI, new ContentValues());
}
}
/**
* 创建保存图片的文件
*/
private File createImageFile() throws IOException {
String imageName = new SimpleDateFormat("yyyyMMddHHmmssSSS", Locale.getDefault()).format(new Date());
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
if (!storageDir.exists()) {
storageDir.mkdir();
}
File tempFile = new File(storageDir, imageName);
if (!Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(tempFile))) {
return null;
}
return tempFile;
}
//接收拍照结果和显示图片
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
if (isAndroidQ) {
// 兼容手机Android 10 使用图片uri加载
// main_iv.setImageURI(mCameraUri);
Bitmap bitmapc = ImageSizeCompress(mCameraUri);//取路径
bitmap = compressScale(bitmapc);
main_iv.setImageBitmap(bitmap);
} else {
//兼容手机 使用图片路径加载
Bitmap bitmapc = BitmapFactory.decodeFile(mCameraImagePath);//取路径
bitmap = compressScale(bitmapc);
main_iv.setImageBitmap(bitmap);
}
}
else
{
Toast.makeText(this,"取消",Toast.LENGTH_LONG).show();
}
}
//调用相册
if (requestCode == 100) {
try {
//做个空值判
Uri uri = data.getData(); //获取数据
ContentResolver contentResolver = getContentResolver();
Bitmap bitmapc = BitmapFactory.decodeStream(contentResolver.openInputStream(uri)); //将对象存入Bitmap中
bitmap = compressScale(bitmapc);
main_iv.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
/**
* 选择相册
*/
public void chooseFromAlbum() {
intent = new Intent();
intent.setType("image/*"); //设定类型为image
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, 100);//选中相片后返回本Activity
}
//Android把uri图片转为bitmap
private Bitmap ImageSizeCompress(Uri uri){
InputStream Stream = null;
InputStream inputStream = null;
try {
//根据uri获取图片的流
inputStream = getContentResolver().openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
//options的in系列的设置了,injustdecodebouond只解析图片的大小,而不加载到内存中去
options.inJustDecodeBounds = true;
//1.如果通过options.outHeight获取图片的宽高,就必须通过decodestream解析同options赋值
//否则options.outheight获取不到宽高
BitmapFactory.decodeStream(inputStream,null,options);
//2.通过 btm.getHeight()获取图片的宽高就不需要1的解析,我这里采取第一张方式
// Bitmap btm = BitmapFactory.decodeStream(inputStream);
//以屏幕的宽高进行压缩
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int heightPixels = displayMetrics.heightPixels;
int widthPixels = displayMetrics.widthPixels;
//获取图片的宽高
int outHeight = options.outHeight;
int outWidth = options.outWidth;
//heightPixels就是要压缩后的图片高度,宽度也一样
int a = (int) Math.ceil((outHeight/(float)heightPixels));
int b = (int) Math.ceil(outWidth/(float)widthPixels);
//比例计算,一般是图片比较大的情况下进行压缩
int max = Math.max(a, b);
if(max > 1){
options.inSampleSize = max;
}
//解析到内存中去
options.inJustDecodeBounds = false;
// 根据uri重新获取流,inputstream在解析中发生改变了
Stream = getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(Stream, null, options);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(inputStream != null) {
inputStream.close();
}
if(Stream != null){
Stream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
//
/ 按大小压缩
public static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 90;
while (baos.toByteArray().length / 1024 > 300) { // 循环判断如果压缩后图片是否大于300kb,大于继续压缩
baos.reset(); // 重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
return bitmap;
}
/
/**
* 图片按比例大小压缩方法
* @param image (根据Bitmap图片压缩)
* @return
*/
public static Bitmap compressScale(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 90, baos);
// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
if (baos.toByteArray().length / 1024 > 1024) {
baos.reset();// 重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 90, baos);// 这里压缩50%,把压缩后的数据存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
BitmapFactory.Options newOpts = new BitmapFactory.Options();
// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
// 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
// float hh = 800f;// 这里设置高度为800f
// float ww = 480f;// 这里设置宽度为480f
float hh = 800f;
float ww = 800f;
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
int be = 1;// be=1表示不缩放
if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
be = 1;
newOpts.inSampleSize = be; // 设置缩放比例
// newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565
// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
//return bitmap;
}