package com.whyc.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Locale; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.graphics.Matrix; //import android.support.media.ExifInterface; import android.graphics.Rect; import android.graphics.YuvImage; import android.media.ExifInterface; import android.media.Image; import android.os.Environment; import android.renderscript.RenderScript; import android.renderscript.ScriptIntrinsicYuvToRGB; import static android.os.Environment.DIRECTORY_DOCUMENTS; public class BitmapUtil { // 把位图对象保存为指定路径的图片文件 public static void saveBitmap(String path, Bitmap bitmap, String format, int quality) { Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG; if (format.toUpperCase(Locale.getDefault()).equals("PNG")) { compressFormat = Bitmap.CompressFormat.PNG; } try { // 根据指定文件路径构建缓存输出流对象 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path)); // 把位图数据压缩到缓存输出流中 bitmap.compress(compressFormat, quality, bos); // 完成缓存输出流的写入动作 bos.flush(); // 关闭缓存输出流 bos.close(); } catch (Exception e) { e.printStackTrace(); } } // 把位图数据保存到指定路径的图片文件 public static void saveBitmap(String path, ByteBuffer buffer, int sample_size, String format, int quality) { try { byte[] buff = new byte[buffer.remaining()]; buffer.get(buff); BitmapFactory.Options ontain = new BitmapFactory.Options(); ontain.inSampleSize = sample_size; Bitmap bitmap = BitmapFactory.decodeByteArray(buff, 0, buff.length, ontain); saveBitmap(path, bitmap, format, quality); } catch (Exception e) { e.printStackTrace(); } } // 从指定路径的图片文件中读取位图数据 public static Bitmap openBitmap(String path) { Bitmap bitmap = null; try { // 根据指定文件路径构建缓存输入流对象 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path)); // 从缓存输入流中解码位图数据 bitmap = BitmapFactory.decodeStream(bis); // 关闭缓存输入流 bis.close(); } catch (Exception e) { e.printStackTrace(); } // 返回图片文件中的位图数据 return bitmap; } // 获得旋转角度之后的位图对象 public static Bitmap getRotateBitmap(Bitmap b, float rotateDegree) { // 创建操作图片用的矩阵对象 Matrix matrix = new Matrix(); // 执行图片的旋转动作 matrix.postRotate(rotateDegree); // 创建并返回旋转后的位图对象 return Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), matrix, false); } // 获得图片的缓存路径 public static String getCachePath(Context context) { return context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/"; } // 按照新的宽高缩放位图对象 public static Bitmap zoomImage(Bitmap origImage, double newWidth, double newHeight) { // 获取原始位图的宽度 float width = origImage.getWidth(); // 获取原始位图的高度 float height = origImage.getHeight(); // 创建操作图片用的矩阵对象 Matrix matrix = new Matrix(); // 计算宽度的缩放率 float scaleWidth = ((float) newWidth) / width; // 计算高度的缩放率 float scaleHeight = ((float) newHeight) / height; // 执行图片的缩放动作 matrix.postScale(scaleWidth, scaleHeight); // 创建并返回缩放后的位图对象 return Bitmap.createBitmap(origImage, 0, 0, (int) width, (int) height, matrix, true); } // 将图片的旋转角度置为0,此方法可以解决某些机型拍照后,图像出现了旋转情况 public static void setPictureDegreeZero(String path) { try { ExifInterface exifInterface = new ExifInterface(path); // 修正图片的旋转角度,设置其不旋转。这里也可以设置其旋转的角度,可以传值过去, // 例如旋转90度,传值ExifInterface.ORIENTATION_ROTATE_90,需要将这个值转换为String类型的 exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, "no"); exifInterface.saveAttributes(); } catch (Exception e) { e.printStackTrace(); } } private static ByteArrayOutputStream stream = new ByteArrayOutputStream(); /**将nv21数据转换为Bitmap*/ public static Bitmap nv21ToBitmap(byte[] nv21, int width, int height) { Bitmap bitmap = null; YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null); //输出到对应流 image.compressToJpeg(new Rect(0, 0, width, height), 100, stream); //对应字节流生成bitmap bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()); //避免中间的byte数组转换步骤,直接从YuvImage写入ByteBuffer,然后使用BitmapFactory的相应方法直接从ByteBuffer创建Bitmap stream.reset(); return bitmap; } /**保存bitmap到文件*/ public static void saveBitmapToFile(Bitmap bitmap) { // 定义图片的保存路径和文件名 String fileName = "IMG_" + System.currentTimeMillis() + ".jpg"; String filePath = Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath() + "/yc_test"+ File.separator + fileName; try( FileOutputStream fos = new FileOutputStream(filePath); BufferedOutputStream bos = new BufferedOutputStream(fos); ){ bitmap.compress(Bitmap.CompressFormat.JPEG, 99, bos); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { bitmap.recycle(); } } /** * 避免中间的byte数组转换步骤,直接从YuvImage写入ByteBuffer,然后使用BitmapFactory的相应方法直接从ByteBuffer创建Bitmap * */ /*public static Bitmap yuvToBitmap(Image image, int width, int height) { //获取YUV数据 *//*int I420size = image.getWidth()*image.getHeight()*3/2; byte[] nv21 = new byte[I420size]; Image.Plane[] planes = image.getPlanes(); int remaining0 = planes[0].getBuffer().remaining(); int remaining1 = planes[1].getBuffer().remaining(); int remaining2 = planes[2].getBuffer().remaining(); //分别准备三个数组接收YUV分量。 byte[] yRawSrcBytes = new byte[remaining0]; byte[] uRawSrcBytes = new byte[remaining1]; byte[] vRawSrcBytes = new byte[remaining2]; planes[0].getBuffer().get(yRawSrcBytes); planes[1].getBuffer().get(uRawSrcBytes); planes[2].getBuffer().get(vRawSrcBytes);*//* int W = image.getWidth(); int H = image.getHeight(); Image.Plane Y = image.getPlanes()[0]; Image.Plane U = image.getPlanes()[1]; Image.Plane V = image.getPlanes()[2]; int Yb = Y.getBuffer().remaining(); int Ub = U.getBuffer().remaining(); int Vb = V.getBuffer().remaining(); byte[] data = new byte[Yb + Ub + Vb]; Y.getBuffer().get(data, 0, Yb); V.getBuffer().get(data, Yb, Vb); U.getBuffer().get(data, Yb + Vb, Ub); RenderScript rs = RenderScript.create(context); ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs)); Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length); Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT); Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H); Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT); final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888); in.copyFromUnchecked(data); yuvToRgbIntrinsic.setInput(in); yuvToRgbIntrinsic.forEach(out); out.copyTo(bmpout); image.close(); return bmpout ; }*/ }