1.工具
import static com.yalantis.ucrop.util.BitmapLoadUtils.calculateInSampleSize;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.util.Base64;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
public class BitmapUtils {
/**
* 从本地读取图片
*
* @param path
* @return
*/
public static Bitmap getBitmapForPath(String path) {
try {
FileInputStream in = new FileInputStream(path);
Bitmap bitmap = BitmapFactory.decodeStream(in);
in.close();
return bitmap;
} catch (Exception e) {
}
return null;
}
/**
* 获取资源文件中的图片
*
* @param context
* @param resourcesId
* @return
*/
public static Drawable getDrawableFormResources(Context context, int resourcesId) {
Resources resources = context.getResources();
return new BitmapDrawable(resources, BitmapFactory.decodeResource(resources, resourcesId));
}
/**
* 从资源文件中获取bitmap对象
*
* @param context
* @param resourcesId
* @return
*/
public static Bitmap getBitmapFromResources(Context context, int resourcesId) {
return BitmapFactory.decodeResource(context.getResources(), resourcesId);
}
/**
* bitmap转byte数组
*
* @param bitmap
* @return
*/
public static byte[] getBitmapbyte(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] datas = baos.toByteArray();
try {
baos.flush();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
return datas;
}
/**
* bitmap转byte数组
*
* @param bitmap
* @return
*/
public static String getBitmapBase64byte(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] datas = baos.toByteArray();
String encodeToString = Base64.encodeToString(datas, Base64.DEFAULT);
try {
baos.flush();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
return encodeToString;
}
/**
* byte转bitmap数组
*
* @param b
* @return
*/
public static Bitmap getBitmaoFrombyte(byte[] b) {
return BitmapFactory.decodeByteArray(b, 0, b.length);
}
/**
* 压缩0
*
* @param srcPath
* @return
*/
public static Bitmap getimageIcon(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 312f;//这里设置高度为800f
float ww = 650f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
/**
* 压缩1
*
* @param srcPath
* @return
*/
public static Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 800f;//这里设置高度为800f
float ww = 480f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
//把bitmap转换成String
// public static String bitmapToString(String filePath) {
//
// Bitmap bm = getSmallBitmap(filePath);
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// bm.compress(Bitmap.CompressFormat.JPEG, 40, baos);
// byte[] b = baos.toByteArray();
// return Base64.encodeToString(b, Base64.DEFAULT);
// }
/**
* 压缩2
*
* @param image
* @return
*/
public static Bitmap comp(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if (baos.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 30, 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
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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 = Bitmap.Config.RGB_565;//降低图片从ARGB888到RGB565
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
/**
* 质量压缩
*
* @param image
* @return
*/
public static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
options -= 20;//每次都减少10
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
return bitmap;
}
/**
* 根据路径获得图片信息并按比例压缩,返回bitmap
*/
public static Bitmap getSmallBitmap(String filePath) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;//只解析图片边沿,获取宽高
BitmapFactory.decodeFile(filePath, options);
// 计算缩放比
options.inSampleSize = calculateInSampleSize(options, 480, 800);
// 完整解析图片返回bitmap
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
/**
* 获取图片大小
*
* @param bitmap
* @return
*/
public static long getBitmapsize(Bitmap bitmap) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
return bitmap.getByteCount();
}
return bitmap.getRowBytes() * bitmap.getHeight();
}
/**
* 转换文件大小
*
* @param fileS
* @return
*/
public static String FormetFileSize(long fileS) {
DecimalFormat df = new DecimalFormat("#.00");
String fileSizeString = "";
String wrongSize = "0B";
if (fileS == 0) {
return wrongSize;
}
if (fileS < 1024) {
fileSizeString = df.format((double) fileS) + "B";
} else if (fileS < 1048576) {
fileSizeString = df.format((double) fileS / 1024) + "KB";
} else if (fileS < 1073741824) {
fileSizeString = df.format((double) fileS / 1048576) + "MB";
} else {
fileSizeString = df.format((double) fileS / 1073741824) + "GB";
}
return fileSizeString;
}
/**
* 获取指定文件大小
*
* @param
* @return
* @throws Exception
*/
private static long getFileSize(File file) throws Exception {
long size = 0;
if (file.exists()) {
FileInputStream fis = null;
fis = new FileInputStream(file);
size = fis.available();
} else {
file.createNewFile();
Log.e("获取文件大小", "文件不存在!");
}
return size;
}
/**
* 对图片进行模糊处理
*
* @param bitmap
* @param context
* @return
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static Bitmap blurBitmap(Bitmap bitmap, Context context) {
Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
RenderScript rs = RenderScript.create(context.getApplicationContext());
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
blurScript.setRadius(25f);
blurScript.setInput(allIn);
blurScript.forEach(allOut);
allOut.copyTo(outBitmap);
bitmap.recycle();
rs.destroy();
return outBitmap;
}
public static Bitmap drawableToBitmap(Drawable drawable) {
Bitmap bitmap = Bitmap.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
//canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
}
/**
* 水平方向模糊度
*/
private static float hRadius = 10;
/**
* 竖直方向模糊度
*/
private static float vRadius = 10;
/**
* 模糊迭代度
*/
private static int iterations = 7;
private static float a = 1.3f;
/**
* 模糊图片
*
* @param bmp
* @return
*/
public static Drawable BoxBlurFilter(Bitmap bmp) {
hRadius = hRadius * a;
vRadius = vRadius * a;
iterations = (int) (iterations * a);
int width = bmp.getWidth();
int height = bmp.getHeight();
int[] inPixels = new int[width * height];
int[] outPixels = new int[width * height];
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bmp.getPixels(inPixels, 0, width, 0, 0, width, height);
for (int i = 0; i < iterations; i++) {
blur(inPixels,
outPixels, width, height, hRadius);
blur(outPixels,
inPixels, height, width, vRadius);
}
blurFractional(inPixels,
outPixels, width, height, hRadius);
blurFractional(outPixels,
inPixels, height, width, vRadius);
bitmap.setPixels(inPixels,
0,
width, 0,
0,
width, height);
Drawable drawable = new BitmapDrawable(bitmap);
return drawable;
}
public static void blur(int[] in, int[] out, int width, int height, float radius) {
int widthMinus1 = width - 1;
int r = (int) radius;
int tableSize = 2 * r + 1;
int divide[] = new int[256 * tableSize];
for (int i = 0; i < 256 * tableSize; i++)
divide[i] = i / tableSize;
int inIndex = 0;
for (int y = 0; y < height; y++) {
int outIndex = y;
int ta = 0, tr = 0, tg = 0, tb = 0;
for (int i = -r; i <= r; i++) {
int rgb = in[inIndex + clamp(i, 0, width - 1)];
ta += (rgb >> 24) & 0xff;
tr += (rgb >> 16) & 0xff;
tg += (rgb >> 8) & 0xff;
tb += rgb & 0xff;
}
for (int x = 0; x < width; x++) {
out[outIndex] = (divide[ta] << 24) | (divide[tr] << 16) | (divide[tg] << 8)
| divide[tb];
int i1 = x + r + 1;
if (i1 > widthMinus1)
i1 = widthMinus1;
int i2 = x - r;
if (i2 < 0)
i2 = 0;
int rgb1 = in[inIndex + i1];
int rgb2 = in[inIndex + i2];
ta += ((rgb1 >> 24) & 0xff) - ((rgb2 >> 24) & 0xff);
tr += ((rgb1 & 0xff0000) - (rgb2 & 0xff0000)) >> 16;
tg += ((rgb1 & 0xff00) - (rgb2 & 0xff00)) >> 8;
tb += (rgb1 & 0xff) - (rgb2 & 0xff);
outIndex += height;
}
inIndex += width;
}
}
public static void blurFractional(int[] in, int[] out, int width, int height, float radius) {
radius -= (int) radius;
float f = 1.0f / (1 + 2 * radius);
int inIndex = 0;
for (int y = 0; y < height; y++) {
int outIndex = y;
out[outIndex] = in[0];
outIndex += height;
for (int x = 1; x < width - 1; x++) {
int i = inIndex + x;
int rgb1 = in[i - 1];
int rgb2 = in[i];
int rgb3 = in[i + 1];
int a1 = (rgb1 >> 24)
& 0xff;
int r1
= (rgb1 >> 16)
& 0xff;
int g1
= (rgb1 >> 8)
& 0xff;
int b1
= rgb1 & 0xff;
int a2
= (rgb2 >> 24)
& 0xff;
int r2
= (rgb2 >> 16)
& 0xff;
int g2
= (rgb2 >> 8)
& 0xff;
int b2
= rgb2 & 0xff;
int a3
= (rgb3 >> 24)
& 0xff;
int r3
= (rgb3 >> 16)
& 0xff;
int g3
= (rgb3 >> 8)
& 0xff;
int b3
= rgb3 & 0xff;
a1
= a2 + (int)
((a1 + a3) * radius);
r1
= r2 + (int)
((r1 + r3) * radius);
g1
= g2 + (int)
((g1 + g3) * radius);
b1
= b2 + (int)
((b1 + b3) * radius);
a1
*= f;
r1
*= f;
g1
*= f;
b1
*= f;
out[outIndex]
= (a1 << 24)
| (r1 << 16)
| (g1 << 8)
| b1;
outIndex
+= height;
}
out[outIndex]
= in[width - 1];
inIndex
+= width;
}
}
public static int clamp(int x,
int a,
int b) {
return (x
< a) ? a : (x > b) ? b : x;
}
public static String getImageUrl(Context context, Uri photoUri) {
String res = null;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(photoUri, proj, null, null, null);
if (cursor.moveToFirst()) {
;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
/**
* 将Bitmap转换成文件
* 保存文件
*
* @param bm
* @param fileName
* @throws IOException
*/
public static File saveFile(Bitmap bm, String path, String fileName) throws IOException {
File dirFile = new File(path);
if (!dirFile.exists()) {
dirFile.mkdir();
}
File myCaptureFile = new File(path, fileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
return myCaptureFile;
}
/**
* File 转 Uri
*/
public static Uri fileTurnUri(File file) {
return Uri.fromFile(file);
}
/**
* 路径转换成file
*
* @param filePath
* @return
*/
public static File BetyToFile(String filePath) {
File file = new File(filePath);
BufferedOutputStream stream = null;
FileOutputStream fstream = null;
byte[] data = new byte[(int) file.length()];
try {
fstream = new FileOutputStream(file);
stream = new BufferedOutputStream(fstream);
stream.write(data);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stream != null) {
stream.close();
}
if (null != fstream) {
fstream.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
return file;
}
}
// path to bitmap
File file0 = new File(avatarPath);
Uri uri0 = Uri.fromFile(file0);
Bitmap bitmap = MediaStore.Images.Media.getBitmap(ctx.getContentResolver(), uri0);
long bitmapsize = BitmapUtils.getBitmapsize(bitmap);
String s = BitmapUtils.FormetFileSize(bitmapsize);
LogUtil.d(TAG, "---文件大小----" + s);
2. 一个不错的工具类
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore.Images;
import android.util.Log;
/**
* 图片压缩工具类
*
*/
public class ImageCompress {
public static final String CONTENT = "content";
public static final String FILE = "file";
/**
* 图片压缩参数
*
* @author Administrator
*
*/
public static class CompressOptions {
public static final int DEFAULT_WIDTH = 400;
public static final int DEFAULT_HEIGHT = 800;
public int maxWidth = DEFAULT_WIDTH;
public int maxHeight = DEFAULT_HEIGHT;
/**
* 压缩后图片保存的文件
*/
public File destFile;
/**
* 图片压缩格式,默认为jpg格式
*/
public CompressFormat imgFormat = CompressFormat.JPEG;
/**
* 图片压缩比例 默认为30
*/
public int quality = 30;
public Uri uri;
}
public Bitmap compressFromUri(Context context,
CompressOptions compressOptions) {
// uri指向的文件路径
String filePath = getFilePath(context, compressOptions.uri);
if (null == filePath) {
return null;
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap temp = BitmapFactory.decodeFile(filePath, options);
int actualWidth = options.outWidth;
int actualHeight = options.outHeight;
int desiredWidth = getResizedDimension(compressOptions.maxWidth,
compressOptions.maxHeight, actualWidth, actualHeight);
int desiredHeight = getResizedDimension(compressOptions.maxHeight,
compressOptions.maxWidth, actualHeight, actualWidth);
options.inJustDecodeBounds = false;
options.inSampleSize = findBestSampleSize(actualWidth, actualHeight,
desiredWidth, desiredHeight);
Bitmap bitmap = null;
Bitmap destBitmap = BitmapFactory.decodeFile(filePath, options);
// If necessary, scale down to the maximal acceptable size.
if (destBitmap.getWidth() > desiredWidth
|| destBitmap.getHeight() > desiredHeight) {
bitmap = Bitmap.createScaledBitmap(destBitmap, desiredWidth,
desiredHeight, true);
destBitmap.recycle();
} else {
bitmap = destBitmap;
}
// compress file if need
if (null != compressOptions.destFile) {
compressFile(compressOptions, bitmap);
}
return bitmap;
}
/**
* compress file from bitmap with compressOptions
*
* @param compressOptions
* @param bitmap
*/
private void compressFile(CompressOptions compressOptions, Bitmap bitmap) {
OutputStream stream = null;
try {
stream = new FileOutputStream(compressOptions.destFile);
} catch (FileNotFoundException e) {
Log.e("ImageCompress", e.getMessage());
}
bitmap.compress(compressOptions.imgFormat, compressOptions.quality,
stream);
}
private static int findBestSampleSize(int actualWidth, int actualHeight,
int desiredWidth, int desiredHeight) {
double wr = (double) actualWidth / desiredWidth;
double hr = (double) actualHeight / desiredHeight;
double ratio = Math.min(wr, hr);
float n = 1.0f;
while ((n * 2) <= ratio) {
n *= 2;
}
return (int) n;
}
private static int getResizedDimension(int maxPrimary, int maxSecondary,
int actualPrimary, int actualSecondary) {
// If no dominant value at all, just return the actual.
if (maxPrimary == 0 && maxSecondary == 0) {
return actualPrimary;
}
// If primary is unspecified, scale primary to match secondary's scaling
// ratio.
if (maxPrimary == 0) {
double ratio = (double) maxSecondary / (double) actualSecondary;
return (int) (actualPrimary * ratio);
}
if (maxSecondary == 0) {
return maxPrimary;
}
double ratio = (double) actualSecondary / (double) actualPrimary;
int resized = maxPrimary;
if (resized * ratio > maxSecondary) {
resized = (int) (maxSecondary / ratio);
}
return resized;
}
/**
* 获取文件的路径
*
* @param scheme
* @return
*/
private String getFilePath(Context context, Uri uri) {
String filePath = null;
if (CONTENT.equalsIgnoreCase(uri.getScheme())) {
Cursor cursor = context.getContentResolver().query(uri,
new String[] { Images.Media.DATA }, null, null, null);
if (null == cursor) {
return null;
}
try {
if (cursor.moveToNext()) {
filePath = cursor.getString(cursor
.getColumnIndex(Images.Media.DATA));
}
} finally {
cursor.close();
}
}
// 从文件中选择
if (FILE.equalsIgnoreCase(uri.getScheme())) {
filePath = uri.getPath();
}
return filePath;
}
}
3.使用如下:
ImageCompress compress = new ImageCompress();
ImageCompress.CompressOptions options = new ImageCompress.CompressOptions();
options.uri = Uri.fromFile(new File(sourcePath));
options.maxWidth=Constants.RESIZEBITMAP_WIDTH;
options.maxHeight=Constants.RESIZEBITMAP_HEIGHT;
Bitmap bitmap = compress.compressFromUri(UploadWithPhotoBaseActivity.this, options);
4.其它图片相关的工具类:
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.util.Base64;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
public class BitmapUtils {
/**
* 从本地读取图片
*
* @param path
* @return
*/
public static Bitmap getBitmapForPath(String path) {
try {
FileInputStream in = new FileInputStream(path);
Bitmap bitmap = BitmapFactory.decodeStream(in);
in.close();
return bitmap;
} catch (Exception e) {
}
return null;
}
/**
* 获取资源文件中的图片
*
* @param context
* @param resourcesId
* @return
*/
public static Drawable getDrawableFormResources(Context context, int resourcesId) {
Resources resources = context.getResources();
return new BitmapDrawable(resources, BitmapFactory.decodeResource(resources, resourcesId));
}
/**
* 从资源文件中获取bitmap对象
*
* @param context
* @param resourcesId
* @return
*/
public static Bitmap getBitmapFromResources(Context context, int resourcesId) {
return BitmapFactory.decodeResource(context.getResources(), resourcesId);
}
/**
* bitmap转byte数组
*
* @param bitmap
* @return
*/
public static byte[] getBitmapbyte(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] datas = baos.toByteArray();
try {
baos.flush();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
return datas;
}
/**
* bitmap转byte数组
*
* @param bitmap
* @return
*/
public static String getBitmapBase64byte(Bitmap bitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] datas = baos.toByteArray();
String encodeToString = Base64.encodeToString(datas, Base64.DEFAULT);
try {
baos.flush();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
return encodeToString;
}
/**
* byte转bitmap数组
*
* @param b
* @return
*/
public static Bitmap getBitmaoFrombyte(byte[] b) {
return BitmapFactory.decodeByteArray(b, 0, b.length);
}
/**
* 压缩0
*
* @param srcPath
* @return
*/
public static Bitmap getimageIcon(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 312f;//这里设置高度为800f
float ww = 650f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
/**
* 压缩1
*
* @param srcPath
* @return
*/
public static Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
float hh = 800f;//这里设置高度为800f
float ww = 480f;//这里设置宽度为480f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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;//设置缩放比例
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
//把bitmap转换成String
// public static String bitmapToString(String filePath) {
//
// Bitmap bm = getSmallBitmap(filePath);
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
// bm.compress(Bitmap.CompressFormat.JPEG, 40, baos);
// byte[] b = baos.toByteArray();
// return Base64.encodeToString(b, Base64.DEFAULT);
// }
/**
* 压缩2
*
* @param image
* @return
*/
public static Bitmap comp(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
if (baos.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
baos.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 30, 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
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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 = Bitmap.Config.RGB_565;//降低图片从ARGB888到RGB565
//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
isBm = new ByteArrayInputStream(baos.toByteArray());
bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
}
/**
* 质量压缩
*
* @param image
* @return
*/
public static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
baos.reset();//重置baos即清空baos
options -= 20;//每次都减少10
image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
return bitmap;
}
/**
* 根据路径获得图片信息并按比例压缩,返回bitmap
*/
public static Bitmap getSmallBitmap(String filePath) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;//只解析图片边沿,获取宽高
BitmapFactory.decodeFile(filePath, options);
// 计算缩放比
options.inSampleSize = calculateInSampleSize(options, 480, 800);
// 完整解析图片返回bitmap
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
/**
* 获取图片大小
*
* @param bitmap
* @return
*/
public static long getBitmapsize(Bitmap bitmap) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
return bitmap.getByteCount();
}
return bitmap.getRowBytes() * bitmap.getHeight();
}
/**
* 转换文件大小
*
* @param fileS
* @return
*/
public static String FormetFileSize(long fileS) {
DecimalFormat df = new DecimalFormat("#.00");
String fileSizeString = "";
String wrongSize = "0B";
if (fileS == 0) {
return wrongSize;
}
if (fileS < 1024) {
fileSizeString = df.format((double) fileS) + "B";
} else if (fileS < 1048576) {
fileSizeString = df.format((double) fileS / 1024) + "KB";
} else if (fileS < 1073741824) {
fileSizeString = df.format((double) fileS / 1048576) + "MB";
} else {
fileSizeString = df.format((double) fileS / 1073741824) + "GB";
}
return fileSizeString;
}
/**
* 获取指定文件大小
*
* @param
* @return
* @throws Exception
*/
private static long getFileSize(File file) throws Exception {
long size = 0;
if (file.exists()) {
FileInputStream fis = null;
fis = new FileInputStream(file);
size = fis.available();
} else {
file.createNewFile();
Log.e("获取文件大小", "文件不存在!");
}
return size;
}
/**
* 对图片进行模糊处理
*
* @param bitmap
* @param context
* @return
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static Bitmap blurBitmap(Bitmap bitmap, Context context) {
Bitmap outBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
RenderScript rs = RenderScript.create(context.getApplicationContext());
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
blurScript.setRadius(25f);
blurScript.setInput(allIn);
blurScript.forEach(allOut);
allOut.copyTo(outBitmap);
bitmap.recycle();
rs.destroy();
return outBitmap;
}
public static Bitmap drawableToBitmap(Drawable drawable) {
Bitmap bitmap = Bitmap.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
//canvas.setBitmap(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
}
/**
* 水平方向模糊度
*/
private static float hRadius = 10;
/**
* 竖直方向模糊度
*/
private static float vRadius = 10;
/**
* 模糊迭代度
*/
private static int iterations = 7;
private static float a = 1.3f;
/**
* 模糊图片
*
* @param bmp
* @return
*/
public static Drawable BoxBlurFilter(Bitmap bmp) {
hRadius = hRadius * a;
vRadius = vRadius * a;
iterations = (int) (iterations * a);
int width = bmp.getWidth();
int height = bmp.getHeight();
int[] inPixels = new int[width * height];
int[] outPixels = new int[width * height];
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bmp.getPixels(inPixels, 0, width, 0, 0, width, height);
for (int i = 0; i < iterations; i++) {
blur(inPixels,
outPixels, width, height, hRadius);
blur(outPixels,
inPixels, height, width, vRadius);
}
blurFractional(inPixels,
outPixels, width, height, hRadius);
blurFractional(outPixels,
inPixels, height, width, vRadius);
bitmap.setPixels(inPixels,
0,
width, 0,
0,
width, height);
Drawable drawable = new BitmapDrawable(bitmap);
return drawable;
}
public static void blur(int[] in, int[] out, int width, int height, float radius) {
int widthMinus1 = width - 1;
int r = (int) radius;
int tableSize = 2 * r + 1;
int divide[] = new int[256 * tableSize];
for (int i = 0; i < 256 * tableSize; i++)
divide[i] = i / tableSize;
int inIndex = 0;
for (int y = 0; y < height; y++) {
int outIndex = y;
int ta = 0, tr = 0, tg = 0, tb = 0;
for (int i = -r; i <= r; i++) {
int rgb = in[inIndex + clamp(i, 0, width - 1)];
ta += (rgb >> 24) & 0xff;
tr += (rgb >> 16) & 0xff;
tg += (rgb >> 8) & 0xff;
tb += rgb & 0xff;
}
for (int x = 0; x < width; x++) {
out[outIndex] = (divide[ta] << 24) | (divide[tr] << 16) | (divide[tg] << 8)
| divide[tb];
int i1 = x + r + 1;
if (i1 > widthMinus1)
i1 = widthMinus1;
int i2 = x - r;
if (i2 < 0)
i2 = 0;
int rgb1 = in[inIndex + i1];
int rgb2 = in[inIndex + i2];
ta += ((rgb1 >> 24) & 0xff) - ((rgb2 >> 24) & 0xff);
tr += ((rgb1 & 0xff0000) - (rgb2 & 0xff0000)) >> 16;
tg += ((rgb1 & 0xff00) - (rgb2 & 0xff00)) >> 8;
tb += (rgb1 & 0xff) - (rgb2 & 0xff);
outIndex += height;
}
inIndex += width;
}
}
public static void blurFractional(int[] in, int[] out, int width, int height, float radius) {
radius -= (int) radius;
float f = 1.0f / (1 + 2 * radius);
int inIndex = 0;
for (int y = 0; y < height; y++) {
int outIndex = y;
out[outIndex] = in[0];
outIndex += height;
for (int x = 1; x < width - 1; x++) {
int i = inIndex + x;
int rgb1 = in[i - 1];
int rgb2 = in[i];
int rgb3 = in[i + 1];
int a1 = (rgb1 >> 24)
& 0xff;
int r1
= (rgb1 >> 16)
& 0xff;
int g1
= (rgb1 >> 8)
& 0xff;
int b1
= rgb1 & 0xff;
int a2
= (rgb2 >> 24)
& 0xff;
int r2
= (rgb2 >> 16)
& 0xff;
int g2
= (rgb2 >> 8)
& 0xff;
int b2
= rgb2 & 0xff;
int a3
= (rgb3 >> 24)
& 0xff;
int r3
= (rgb3 >> 16)
& 0xff;
int g3
= (rgb3 >> 8)
& 0xff;
int b3
= rgb3 & 0xff;
a1
= a2 + (int)
((a1 + a3) * radius);
r1
= r2 + (int)
((r1 + r3) * radius);
g1
= g2 + (int)
((g1 + g3) * radius);
b1
= b2 + (int)
((b1 + b3) * radius);
a1
*= f;
r1
*= f;
g1
*= f;
b1
*= f;
out[outIndex]
= (a1 << 24)
| (r1 << 16)
| (g1 << 8)
| b1;
outIndex
+= height;
}
out[outIndex]
= in[width - 1];
inIndex
+= width;
}
}
public static int clamp(int x,
int a,
int b) {
return (x
< a) ? a : (x > b) ? b : x;
}
public static String getImageUrl(Context context, Uri photoUri) {
String res = null;
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(photoUri, proj, null, null, null);
if (cursor.moveToFirst()) {
;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
return res;
}
/**
* 将Bitmap转换成文件
* 保存文件
*
* @param bm
* @param fileName
* @throws IOException
*/
public static File saveFile(Bitmap bm, String path, String fileName) throws IOException {
File dirFile = new File(path);
if (!dirFile.exists()) {
dirFile.mkdir();
}
File myCaptureFile = new File(path, fileName);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
bos.flush();
bos.close();
return myCaptureFile;
}
/**
* File 转 Uri
*/
public static Uri fileTurnUri(File file) {
return Uri.fromFile(file);
}
/**
* 路径转换成file
*
* @param filePath
* @return
*/
public static File BetyToFile(String filePath) {
File file = new File(filePath);
BufferedOutputStream stream = null;
FileOutputStream fstream = null;
byte[] data = new byte[(int) file.length()];
try {
fstream = new FileOutputStream(file);
stream = new BufferedOutputStream(fstream);
stream.write(data);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stream != null) {
stream.close();
}
if (null != fstream) {
fstream.close();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
return file;
}
}
Bitmap loadbitmap = BitmapFactory.decodeFile(realPathFromURI, getBitmapOption(2));
try {
File file1 = BitmapUtils.saveFile(loadbitmap, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + "CropImage", "ppp.jpg");
LogUtil.d(TAG, "---文件----" + file1);
// File file2 = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + "CropImage","ppp.jpg");
Uri uri = BitmapUtils.fileTurnUri(file1);
LogUtil.d(TAG, "---文件uri----" + uri);
String path = getRealPathFromURI(uri);
String path1 = file1.getPath();
LogUtil.d(TAG, "---文件path----" + path1);
// path to bitmap
File file0 = new File(path1);
Uri uri0 = Uri.fromFile(file0);
Bitmap bitmap = MediaStore.Images.Media.getBitmap(ctx.getContentResolver(), uri0);
long bitmapsize = BitmapUtils.getBitmapsize(bitmap);
String s = BitmapUtils.FormetFileSize(bitmapsize);
LogUtil.d(TAG, "---文件大小----" + s);
// sendFile(path1);
} catch (IOException e) {
throw new RuntimeException(e);
}
5.压缩图片并保存到本地:
/**
* @param path
* @return
* @throws IOException
* 压缩图片
*/
public static Bitmap revitionImageSize(String path) throws IOException {
//根据文件路径,创建一个字节缓冲输入流
BufferedInputStream in = new BufferedInputStream(new FileInputStream(
new File(path)));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
//根据流返回一个位图也就是bitmap,当options.inJustDecodeBounds = true的时候不需要完全解码,
// 它仅仅会把它的宽,高取回来给你,这样就不会占用太多的内存,也就不会那么频繁的发生OOM了
BitmapFactory.decodeStream(in, null, options);
//关闭流
in.close();
int i = 0;
Bitmap bitmap = null;
while (true) {
// options.outWidth >> i 。右移运算符,num >> 1,相当于num除以2
if ((options.outWidth >> i <= 1000) && (options.outHeight >> i <= 1000)) {
//得到一个输入流
in = new BufferedInputStream(new FileInputStream(new File(path)));
//为了解决图片解码时候出现SanpleSize错误,设置恰当的inSampleSize可以使BitmapFactory分配更少的空间以消除该错误
//你将 inSampleSize 赋值为2,那就是每隔2行采1行,每隔2列采一列,那你解析出的图片就是原图大小的1/4.
// Math.pow(2.0D, i)次方运算,2的i次方是多少
options.inSampleSize = (int) Math.pow(2.0D, i);
// 这里之前设置为了true,所以要改为false,否则就创建不出图片
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeStream(in, null, options);
break;
}
i += 1;
}
return bitmap;
}
/**
* @param bitmap
* 保存图片到SD卡的方法
*/
public void saveBitmapFile(Bitmap bitmap){
//Environment.getExternalStorageDirectory() 获取Android外部存储的空间,当有外部SD卡就在外部SD卡上建立。
//没有外部SD卡就在内部SD卡的非data/data/目录建立目录。(data/data/目录才是真正的内存目录。)
//IMAGE_NAME文件的名字,随便起。比如(xxx.jpg)
File tempFile = new File(Environment.getExternalStorageDirectory(), IMAGE_NAME );
try {
//创建一个输出流,将数据写入到创建的文件对象中。
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tempFile));
30 是压缩率,表示压缩70%; 如果不压缩是100,
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
/* 为什么要调用flush()方法?当FileOutputStream作为BufferedOutputStream构造函数的参数传入,然后对BufferedOutputStream进行写入操作,才能利用缓冲及flush()。
查看BufferedOutputStream的源代码,发现所谓的buffer其实就是一个byte[]。
BufferedOutputStream的每一次write其实是将内容写入byte[],当buffer容量到达上限时,会触发真正的磁盘写入。
而另一种触发磁盘写入的办法就是调用flush()了。*/
bos.flush();
//关闭流对象
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
6.其它压缩借鉴:
dependencies {
//compile 'top.zibin:Luban:1.1.2'
implementation 'top.zibin:Luban:1.1.8'
}