
图片压缩处理
发布日期:2021-05-09 18:26:49
浏览次数:20
分类:精选文章
本文共 16350 字,大约阅读时间需要 54 分钟。
网上有很多的图片压缩处理的代码和框架,这里给大家推荐一个非常好用的图片压缩的代码
实现效果图:对于拍照的图片进行压缩处理,至于相册选取图片不在本文讨论,你可以找到图片的绝对路径
(2)记得申请拍照权限
(3)布局文件太过简单不贴了,你们需要的自行补齐,下面是主界面调用方法,做图片压缩处理
import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date;public class MainActivity extends AppCompatActivity implements LGImgCompressor.CompressListener{ private final String TAG = MainActivity.class.getSimpleName(); private ImageView imageView; private TextView imageInfo; private final static int CAMERA_REQESTCODE = 100; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageInfo = (TextView) findViewById(R.id.image_info); imageView = (ImageView) findViewById(R.id.image_view); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { requestPermission(); } }); } //处理6.0动态权限问题 private void requestPermission() { if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, CAMERA_REQESTCODE); } else { takePictureFormCamera(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (requestCode == CAMERA_REQESTCODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { takePictureFormCamera(); } else { Toast.makeText(this, "需要允许写入权限来存储图片", Toast.LENGTH_LONG).show(); } } } private File imageFile; private void takePictureFormCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); String fileName = timeStamp + "_"; File fileDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); imageFile = null; try { imageFile = File.createTempFile(fileName, ".jpg", fileDir); } catch (IOException e) { e.printStackTrace(); } intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile)); startActivityForResult(intent, CAMERA_REQESTCODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { if (requestCode == CAMERA_REQESTCODE) { LGImgCompressor.getInstance(this).withListener(this). starCompress(Uri.fromFile(imageFile).toString(), 600, 800, 100);// LGImgCompressor.getInstance(this).withListener(this).// starCompressWithDefault(Uri.fromFile(imageFile).toString()); } } } @Override public void onCompressStart() { Log.d(TAG, "onCompressStart"); } @Override public void onCompressEnd(LGImgCompressor.CompressResult compressResult) { Log.d(TAG, "onCompressEnd outPath:" + compressResult.getOutPath()); if (compressResult.getStatus() == LGImgCompressor.CompressResult.RESULT_ERROR)//压缩失败 return; File file = new File(compressResult.getOutPath()); Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), Uri.fromFile(file)); imageView.setImageBitmap(bitmap); float imageFileSize = file.length() / 1024f; imageInfo.setText("image info width:" + bitmap.getWidth() + " \nheight:" + bitmap.getHeight() + " \nsize:" + imageFileSize + "kb" + "\nimagePath:" + file.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } }}
(5)图片处理类LGImgCompressor
import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.media.ExifInterface; import android.net.Uri; import android.os.AsyncTask; import android.os.Environment; import android.os.Parcel; import android.os.Parcelable; import android.provider.MediaStore; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;/** * Created by guizhigang on 16/5/25. */public class LGImgCompressor { private static LGImgCompressor instance = null; private Context context; private CompressListener compressListener; private static final int DEFAULT_OUTWIDTH = 720; private static final int DEFAULT_OUTHEIGHT = 1080; private static final int DEFAULT_MAXFILESIZE = 1024;//KB private LGImgCompressor(Context context) { this.context = context; } public static LGImgCompressor getInstance(Context context) { if (instance == null) { synchronized (LGImgCompressor.class) { if (instance == null) instance = new LGImgCompressor(context.getApplicationContext()); } } return instance; } public LGImgCompressor withListener(CompressListener compressListener) { this.compressListener = compressListener; return this; } /** * 通过uri地址获取文件路径 * @param uri * @return */ private String getFilePathFromUri(String uri) { Uri pathUri = Uri.parse(uri); Cursor cursor = context.getContentResolver().query(pathUri, null, null, null, null); if (cursor == null) { return pathUri.getPath(); } else { cursor.moveToFirst(); int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); String str = cursor.getString(index); cursor.close(); return str; } } /** * Can't compress a recycled bitmap * @param srcImageUri 原始图片的uri路径 * @param outWidth 期望的输出图片的宽度 * @param outHeight 期望的输出图片的高度 * @param maxFileSize 期望的输出图片的最大占用的存储空间 * @return */ public String compressImage(String srcImageUri, int outWidth, int outHeight, int maxFileSize) { String srcImagePath = getFilePathFromUri(srcImageUri); //进行大小缩放来达到压缩的目的 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(srcImagePath, options); //根据原始图片的宽高比和期望的输出图片的宽高比计算最终输出的图片的宽和高 float srcWidth = options.outWidth; float srcHeight = options.outHeight; float maxWidth = outWidth; float maxHeight = outHeight; float srcRatio = srcWidth / srcHeight; float outRatio = maxWidth / maxHeight; float actualOutWidth = srcWidth; float actualOutHeight = srcHeight; if (srcWidth > maxWidth || srcHeight > maxHeight) { //如果输入比率小于输出比率,则最终输出的宽度以maxHeight为准() //比如输入比为10:20 输出比是300:10 如果要保证输出图片的宽高比和原始图片的宽高比相同,则最终输出图片的高为10 //宽度为10/20 * 10 = 5 最终输出图片的比率为5:10 和原始输入的比率相同 //同理如果输入比率大于输出比率,则最终输出的高度以maxHeight为准() //比如输入比为20:10 输出比是5:100 如果要保证输出图片的宽高比和原始图片的宽高比相同,则最终输出图片的宽为5 //高度需要根据输入图片的比率计算获得 为5 / 20/10= 2.5 最终输出图片的比率为5:2.5 和原始输入的比率相同 if (srcRatio < outRatio) { actualOutHeight = maxHeight; actualOutWidth = actualOutHeight * srcRatio; } else if (srcRatio > outRatio) { actualOutWidth = maxWidth; actualOutHeight = actualOutWidth / srcRatio; } else { actualOutWidth = maxWidth; actualOutHeight = maxHeight; } } options.inSampleSize = computSampleSize(options, actualOutWidth, actualOutHeight); options.inJustDecodeBounds = false; Bitmap scaledBitmap = null; try { scaledBitmap = BitmapFactory.decodeFile(srcImagePath, options); } catch (OutOfMemoryError e) { e.printStackTrace(); } if (scaledBitmap == null) { return null;//压缩失败 } //生成最终输出的bitmap Bitmap actualOutBitmap = Bitmap.createScaledBitmap(scaledBitmap, (int) actualOutWidth, (int) actualOutHeight, true); if(actualOutBitmap != scaledBitmap) scaledBitmap.recycle(); //处理图片旋转问题 ExifInterface exif = null; try { exif = new ExifInterface(srcImagePath); int orientation = exif.getAttributeInt( ExifInterface.TAG_ORIENTATION, 0); Matrix matrix = new Matrix(); if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { matrix.postRotate(90); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { matrix.postRotate(180); } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { matrix.postRotate(270); } actualOutBitmap = Bitmap.createBitmap(actualOutBitmap, 0, 0, actualOutBitmap.getWidth(), actualOutBitmap.getHeight(), matrix, true); } catch (IOException e) { e.printStackTrace(); return null; } //进行有损压缩 ByteArrayOutputStream baos = new ByteArrayOutputStream(); int options_ = 100; actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//质量压缩方法,把压缩后的数据存放到baos中 (100表示不压缩,0表示压缩到最小) int baosLength = baos.toByteArray().length; while (baosLength / 1024 > maxFileSize) {//循环判断如果压缩后图片是否大于maxMemmorrySize,大于继续压缩 baos.reset();//重置baos即让下一次的写入覆盖之前的内容 options_ = Math.max(0, options_ - 10);//图片质量每次减少10 actualOutBitmap.compress(Bitmap.CompressFormat.JPEG, options_, baos);//将压缩后的图片保存到baos中 baosLength = baos.toByteArray().length; if (options_ == 0)//如果图片的质量已降到最低则,不再进行压缩 break; } actualOutBitmap.recycle(); //将bitmap保存到指定路径 FileOutputStream fos = null; String filePath = getOutputFileName(srcImagePath); try { fos = new FileOutputStream(filePath); //包装缓冲流,提高写入速度 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fos); bufferedOutputStream.write(baos.toByteArray()); bufferedOutputStream.flush(); } catch (FileNotFoundException e) { return null; } catch (IOException e) { return null; } finally { if (baos != null) { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } return filePath; } private int computSampleSize(BitmapFactory.Options options, float reqWidth, float reqHeight) { float srcWidth = options.outWidth;//20 float srcHeight = options.outHeight;//10 int sampleSize = 1; if (srcWidth > reqWidth || srcHeight > reqHeight) { int withRatio = Math.round(srcWidth / reqWidth); int heightRatio = Math.round(srcHeight / reqHeight); sampleSize = Math.min(withRatio, heightRatio); } return sampleSize; } private String getOutputFileName(String srcFilePath) { File srcFile = new File(srcFilePath); File file = new File(Environment.getExternalStorageDirectory().getPath(), "LGImgCompressor/Images"); if (!file.exists()) { file.mkdirs(); } String uriSting = (file.getAbsolutePath() + File.separator + srcFile.getName()); return uriSting; } public void starCompress(String srcImageUri, int outWidth, int outHeight, int maxFileSize) { new CompressTask().execute(srcImageUri, "" + outWidth, "" + outHeight, "" + maxFileSize); } public void starCompressWithDefault(String srcImageUri) { new CompressTask().execute(srcImageUri, "" + DEFAULT_OUTWIDTH, "" + DEFAULT_OUTHEIGHT, "" + DEFAULT_MAXFILESIZE); } public static class CompressResult implements Parcelable{ public static final int RESULT_OK = 0; public static final int RESULT_ERROR = 1; private int status = RESULT_OK; private String srcPath; private String outPath; public CompressResult(){ } protected CompressResult(Parcel in) { status = in.readInt(); srcPath = in.readString(); outPath = in.readString(); } public static final CreatorCREATOR = new Creator () { @Override public CompressResult createFromParcel(Parcel in) { return new CompressResult(in); } @Override public CompressResult[] newArray(int size) { return new CompressResult[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(status); dest.writeString(srcPath); dest.writeString(outPath); } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getSrcPath() { return srcPath; } public void setSrcPath(String srcPath) { this.srcPath = srcPath; } public String getOutPath() { return outPath; } public void setOutPath(String outPath) { this.outPath = outPath; } } /** * 压缩结果回到监听类 */ public interface CompressListener { void onCompressStart(); void onCompressEnd(CompressResult imageOutPath); } private class CompressTask extends AsyncTask { @Override protected CompressResult doInBackground(String... params) { String path = params[0]; int outWidth = Integer.parseInt(params[1]); int outHeight = Integer.parseInt(params[2]); int maxFileSize = Integer.parseInt(params[3]); CompressResult compressResult = new CompressResult(); String outPutPath = null; try { outPutPath = compressImage(path, outWidth, outHeight, maxFileSize); }catch (Exception e){ } compressResult.setSrcPath(path); compressResult.setOutPath(outPutPath); if(outPutPath == null){ compressResult.setStatus(CompressResult.RESULT_ERROR); } return compressResult; } @Override protected void onPreExecute() { if (compressListener != null) { compressListener.onCompressStart(); } } @Override protected void onPostExecute(CompressResult compressResult) { if (compressListener != null) { compressListener.onCompressEnd(compressResult); } } }}
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年04月16日 21时57分26秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
eclipse自动补全代码(Auto activation只能输3个字符)
2021-05-10
svn commit failed:is scheduled for addition
2021-05-10
P2550 [AHOI2001]彩票摇奖
2021-05-10
初学java:斐波那契数列的java实现
2021-05-10
Java多线程
2021-05-10
Unity监听日记
2021-05-10
Android SD卡
2021-05-10
Android编写电话拨号器
2021-05-10
AndroidStudio跳到错误位置
2021-05-10
ARFoundation系列讲解-41图像重新识别
2021-05-10
unity 四元数和欧拉角相互转换
2021-05-10
ARFoundation系列讲解-03申请苹果开发者账号
2021-05-10
ARFoundation系列讲解-43播放视频
2021-05-10
Unity四中常用路径
2021-05-10
直接点不玩虚的--启明云端千元现金红包、50pcs开发板直播现场拿走不谢
2021-05-10
木马开发的基本理论基础(五)
2021-05-10
windows中如何让chrome信任自签名证书?
2021-05-10
openssl服务器证书操作
2021-05-10
expect 模拟交互 ftp 上传文件到指定目录下
2021-05-10
Matplotlib绘制分组聚合流程图
2021-05-10