Android 处理大图片
来源:互联网 发布:网络电视显示无信号 编辑:程序博客网 时间:2024/05/16 02:08
package com.example.utils;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.nio.ByteBuffer;import java.nio.channels.Channels;import java.nio.channels.ReadableByteChannel;import android.annotation.SuppressLint;import android.content.Context;import android.content.Intent;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;import android.graphics.BitmapFactory.Options;import android.graphics.Matrix;import android.media.ExifInterface;import android.net.Uri;import android.os.Build;public class BitmapUtils { public final static int getDegress(String path) { int degree = 0; try { ExifInterface exifInterface = new ExifInterface(path); int orientation = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 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; } } catch (IOException e) { e.printStackTrace(); } return degree; } public static Bitmap rotateBitmap(Bitmap bitmap, int degress) { if (bitmap != null) { Matrix m = new Matrix(); m.postRotate(degress); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true); return bitmap; } return bitmap; } public final static int caculateInSampleSize(BitmapFactory.Options options, int rqsW, int rqsH) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (rqsW == 0 || rqsH == 0) return 1; if (height > rqsH || width > rqsW) { final int heightRatio = Math.round((float) height/ (float) rqsH); final int widthRatio = Math.round((float) width / (float) rqsW); inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } /** * 压缩指定路径的图片,并得到图片对象 * @param context * @param path bitmap source path * @return Bitmap {@link android.graphics.Bitmap} */ public final static Bitmap compressBitmap(String path, int rqsW, int rqsH) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); options.inSampleSize = caculateInSampleSize(options, rqsW, rqsH); options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path, options); } /** * 压缩指定路径图片,并将其保存在缓存目录中,通过isDelSrc判定是否删除源文件,并获取到缓存后的图片路径 * @param context * @param srcPath * @param rqsW * @param rqsH * @param isDelSrc * @return */ public final static String compressBitmap(Context context, String srcPath,String desPath, int rqsW, int rqsH, boolean isDelSrc) { Bitmap bitmap = compressBitmap(srcPath, rqsW, rqsH); File srcFile = new File(srcPath); int degree = getDegress(srcPath); try { if (degree != 0) bitmap = rotateBitmap(bitmap, degree); File file = new File(desPath); if(srcFile.getAbsolutePath() != file.getAbsolutePath()){ FileOutputStream fos = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.PNG, 40, fos); fos.close(); } if (isDelSrc) srcFile.deleteOnExit(); } catch (Exception e) { e.printStackTrace(); } return desPath; } /** * 刷新相册 * @param context * @param imgFileName */ private static void scanPhoto(Context context, String imgFileName) { Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE"); File file = new File(imgFileName); Uri contentUri = Uri.fromFile(file); mediaScanIntent.setData(contentUri); context.sendBroadcast(mediaScanIntent); } /** * 压缩某个输入流中的图片,可以解决网络输入流压缩问题,并得到图片对象 * @param context * @param path bitmap source path * @return Bitmap {@link android.graphics.Bitmap} */ public final static Bitmap compressBitmap(InputStream is, int reqsW, int reqsH) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ReadableByteChannel channel = Channels.newChannel(is); ByteBuffer buffer = ByteBuffer.allocate(1024); while (channel.read(buffer) != -1) { buffer.flip(); while (buffer.hasRemaining()) baos.write(buffer.get()); buffer.clear(); } byte[] bts = baos.toByteArray(); Bitmap bitmap = compressBitmap(bts, reqsW, reqsH); is.close(); channel.close(); baos.close(); return bitmap; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 压缩指定byte[]图片,并得到压缩后的图像 * @param bts * @param reqsW * @param reqsH * @return */ public final static Bitmap compressBitmap(byte[] bts, int reqsW, int reqsH) { final Options options = new Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(bts, 0, bts.length, options); options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH); options.inJustDecodeBounds = false; return BitmapFactory.decodeByteArray(bts, 0, bts.length, options); } /** * 压缩已存在的图片对象,并返回压缩后的图片 * @param bitmap * @param reqsW * @param reqsH * @return */ public final static Bitmap compressBitmap(Bitmap bitmap, int reqsW, int reqsH) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.PNG, 100, baos); byte[] bts = baos.toByteArray(); Bitmap res = compressBitmap(bts, reqsW, reqsH); baos.close(); return res; } catch (IOException e) { e.printStackTrace(); return bitmap; } } /** * 压缩资源图片,并返回图片对象 * @param res {@link android.content.res.Resources} * @param resID * @param reqsW * @param reqsH * @return */ public final static Bitmap compressBitmap(Resources res, int resID, int reqsW, int reqsH) { final Options options = new Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resID, options); options.inSampleSize = caculateInSampleSize(options, reqsW, reqsH); options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resID, options); } /** * 基于质量的压缩算法, 此方法未 解决压缩后图像失真问题 * <br> 可先调用比例压缩适当压缩图片后,再调用此方法可解决上述问题 * @param bts * @param maxBytes 压缩后的图像最大大小 单位为byte * @return */ public final static Bitmap compressBitmap(Bitmap bitmap, long maxBytes) { try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(CompressFormat.PNG, 100, baos); int options = 90; while (baos.toByteArray().length > maxBytes) { baos.reset(); bitmap.compress(CompressFormat.PNG, options, baos); options -= 10; } byte[] bts = baos.toByteArray(); Bitmap bmp = BitmapFactory.decodeByteArray(bts, 0, bts.length); baos.close(); return bmp; } catch (IOException e) { e.printStackTrace(); return null; } } /** * 得到指定路径图片的options * @param srcPath * @return Options {@link android.graphics.BitmapFactory.Options} */ public final static Options getBitmapOptions(String srcPath) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(srcPath, options); return options; } /** * 获取本地图片byte[] * @param bmp * @param needRecycle * @return */ public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) { ByteArrayOutputStream output = new ByteArrayOutputStream(); bmp.compress(CompressFormat.PNG, 100, output); if (needRecycle) { bmp.recycle(); } byte[] result = output.toByteArray(); try { output.close(); } catch (Exception e) { e.printStackTrace(); } return result; } public static void closeStream(OutputStream os){ if(os != null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void closeStream(InputStream os){ if(os != null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } @SuppressLint("NewApi") public static int getBitmapsize(Bitmap bp){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) { return bp.getByteCount() / 1024; } return bp.getRowBytes() * bp.getHeight() / 1024; } /** * 初步处理大图片 :大小压缩 * @param imgFilePath * @param smartSpace * @return */ public static Bitmap scaleCompressBp(String imgFilePath,long smartSpace){ File file = new File(imgFilePath); if(!file.exists() || !file.isFile()){ throw new IllegalArgumentException("file not exists or file is not a image file"); } long scalebefore = (file.length()/1024)/smartSpace; double sqrt = Math.sqrt(scalebefore); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; if((int)sqrt <= 1) sqrt = 1; options.inSampleSize = (int) sqrt; return BitmapFactory.decodeFile(imgFilePath,options); } /** * 进一步处理图片 : 进行质量压缩 * desSize 不能太小失真很严重 * @param bitmap * @param desSize * @return */ private static byte[] qualityCompressBp(Bitmap bitmap,int desSize) { byte[] desBytes = null; ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos); int options = 100; int length = baos.toByteArray().length; while (length / 1024 > desSize) { baos.reset(); bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos); options -= 3; if(options <= 10) break; } desBytes = baos.toByteArray(); closeStream(baos); return desBytes; } /** * 对图片进行压缩处理 * 在 华为4x 1300万摄像头下进行测试的结果 原始图片 2.49M 压缩后在300kb左右 其中smartSpace 50 desSize 300 * 根据处理文件大小的不同 来设置相应的smartSpace因子 和 desSize; * @param imgFilePath 原始图片文件路径 * @param smartSpace * @return */ public static Bitmap smartCompressBp(String imgFilePath,long smartSpace,int desSize){ Bitmap scaleCompressBp = scaleCompressBp(imgFilePath,smartSpace); byte[] qualityCompressBp = qualityCompressBp(scaleCompressBp,desSize); return BitmapFactory.decodeByteArray(qualityCompressBp, 0, qualityCompressBp.length); } // 初步压缩 :大小压缩 public static Bitmap scaleCompressBp(Bitmap bp,long smartSpace){ long scalebefore = getBitmapsize(bp)/smartSpace; double sqrt = Math.sqrt(scalebefore); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; if((int)sqrt <= 1) sqrt = 1; options.inSampleSize = (int) sqrt; ByteArrayOutputStream aos = new ByteArrayOutputStream(); bp.compress(Bitmap.CompressFormat.JPEG, 100, aos); return BitmapFactory.decodeByteArray(aos.toByteArray(), 0, aos.toByteArray().length); } // 对中等大小的图片进行处理 比如对 700kb大图片进行处理 public static Bitmap smartCompressBp(Bitmap srcBitmap,long smartSpace,int desSize){ Bitmap scaleCompressBp = scaleCompressBp(srcBitmap,smartSpace); byte[] qualityCompressBp = qualityCompressBp(scaleCompressBp,desSize); return BitmapFactory.decodeByteArray(qualityCompressBp, 0, qualityCompressBp.length); }}
0 0
- Android处理大图片
- Android大图片处理
- Android 处理大图片
- Android大图片处理
- Android大图片处理
- android 加载大图片处理
- Android的Bitmap处理大图片解决方法
- Android的Btimap处理大图片解决方法
- Android的Btimap处理大图片解决方案
- iOS处理大图片
- android_62_大图片处理
- Android 加载大图片
- android下载大图片
- android 加载大图片
- android加载大图片
- Android-加载大图片
- android加载大图片
- Android大图片裁剪
- 虚拟存储器的实现方法
- Xcode提示“expression is not assignable”
- 了解使用Android ConstraintLayout (Google I/O 2016)
- c解决打鱼晒网问题
- 匿名---项目总结
- Android 处理大图片
- python3实现打印乘法口诀表
- android-R.attr(一)
- Python __init__ 构造函数生成对象时调用关系
- Android 无障碍服务一 让应用具有辅助性服务
- java实现解析xml数据为list
- Retrofit 2.x版的不同之处
- 机器学习之RBM(Restricted Boltzmann Machines,受限玻尔兹曼机)
- C++ auto_ptr