Android图片压缩、Drawable和Bitmap转换、bitmap和base64转换、网络资源图片转化成bitmap、base64编码转化成图片
1. Android图片压缩、Drawable和Bitmap转换、bitmap和base64转换1.1. Drawable和Bitmap之间的转化1.1.1. bitmap和Drawable间的区别 Bitmap - 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565、RGB888。作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低。我们理解为一种存储对象比较
1. Android图片压缩、Drawable和Bitmap转换、bitmap和base64转换、网络资源图片转化成bitmap
1.1. Drawable和Bitmap之间的转化
1.1.1. bitmap和Drawable间的区别
Bitmap - 称作位图,一般位图的文件格式后缀为bmp,当然编码器也有很多如RGB565、RGB888。作为一种逐像素的显示对象执行效率高,但是缺点也很明显存储效率低。我们理解为一种存储对象比较好。
Drawable - 作为Android平下通用的图形对象,它可以装载常用格式的图像,比如GIF、PNG、JPG,当然也支持BMP,当然还提供一些高级的可视化对象,比如渐变、图形等。
两者间的简单对比:
对比项 | Bitmip | Drawable |
---|---|---|
显示清晰度 | 相同 | 相同 |
电内存占比 | 大 | 小 |
支持压缩 | 是 | 是 |
支持色相色差调整 | 是 | 否 |
支持旋转 | 是 | 是 |
支持透明色 | 是 | 是 |
绘图速度 | 慢 | 快 |
支持像素操作 | 是 | 否 |
Drawable在内存占用和绘制速度这两个非常关键的点上胜过Bitmap
我们经常会遇到需要在代码中获取资源文件下图片的问题
Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.drawable.ic );
或者
Drawable drawable = getResources().getDrawable(R.drawable.ic);
或者
iv.setImageResource(R.drawable.ic_launcher);
获取路径下的图片资源:
String fileName = "/data/data/com.test/aa.png;
Bitmap bm = BitmapFactory.decodeFile(fileName);
iv.setImageBitmap(bm); //占用内存
1.1.2. Drawable转换成Bitmap
第一种:
BitmapDrawable bd = (BitmapDrawable) drawable;
Bitmap bm= bd.getBitmap();
第二种:
public static Bitmap drawableToBitmap(Drawable drawable) {
// 取 drawable 的长宽
int w = drawable.getIntrinsicWidth();
int h = drawable.getIntrinsicHeight();
// 取 drawable 的颜色格式
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
: Bitmap.Config.RGB_565;
// 建立对应 bitmap
Bitmap bitmap = Bitmap.createBitmap(w, h, config);
// 建立对应 bitmap 的画布
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, w, h);
// 把 drawable 内容画到画布中
drawable.draw(canvas);
return bitmap;
}
1.1.3. Bitmap转换成Drawable
第一种:
Drawable drawable = new BitmapDrawable(bitmap);
第二种:
BitmapDrawable bd= new BitmapDrawable(getResource(), bm);
BitmapDrawable是Drawable的子类,可以直接使用。
1.2. Drawable和Bitmap之间的转化
1.2.1. bitmap和base64之间的转换
public class BitmapUtil {
/**
* bitmap转为base64
* @param bitmap
* @return
*/
public static String bitmapToBase64(Bitmap bitmap) {
String result = null;
ByteArrayOutputStream baos = null;
try {
if (bitmap != null) {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* base64转为bitmap
* @param base64Data
* @return
*/
public static Bitmap base64ToBitmap(String base64Data) {
byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
}
1.2.2. 注意事项
当我们通过站长工具进行图片和Base64的转换时,会有一段前缀信息data:image/jpeg;base64,
如果Base64中带有这样的前缀信息,我们需要将其去除之后,才能调用上面的Bitmap.base64ToBitmap()方法,将其转换为Bitmap。
1.2.3. bitmap转换工具
package ***.***.***.***;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Base64;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.ImageView;
import com.***.***.R;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 描述:图片处理类.
*
*/
public class AbImageUtil {
/**
* The tag.
*/
private static String TAG = "AbImageUtil";
private static OnImageUtilsListener onImageUtilsListener;
public void setOnImageUtilsListener(OnImageUtilsListener listener) {
onImageUtilsListener = listener;
}
public interface OnImageUtilsListener {
void backBitmap(Bitmap bt);
}
/**
* 描述:缩放图片.压缩
*
* @param file File对象
* @param newWidth 新图片的宽
* @param newHeight 新图片的高
* @return Bitmap 新图片
*/
@SuppressWarnings("resource")
public static Bitmap scaleImg(File file, int newWidth, int newHeight) {
Bitmap resizeBmp = null;
try {
BitmapFactory.Options opts = new BitmapFactory.Options();
// 设置为true,decodeFile先不创建内存 只获取一些解码边界信息即图片大小信息
opts.inJustDecodeBounds = true;
// BitmapFactory.decodeFile(file.getPath(), opts);
BitmapFactory.decodeFileDescriptor(new FileInputStream(file.getPath()).getFD(), null, opts);
if (newWidth != -1 && newHeight != -1) {
// inSampleSize=2表示图片宽高都为原来的二分之一,即图片为原来的四分之一
// 缩放可以将像素点打薄
int srcWidth = opts.outWidth; // 获取图片的原始宽度
int srcHeight = opts.outHeight;// 获取图片原始高度
int destWidth = 0;
int destHeight = 0;
// 缩放的比例
double ratio = 0.0;
if (srcWidth < newWidth || srcHeight < newHeight) {
ratio = 0.0;
destWidth = srcWidth;
destHeight = srcHeight;
// 按比例计算缩放后的图片大小
} else if (srcWidth > srcHeight) {
ratio = (double) srcWidth / newWidth;
destWidth = newWidth;
destHeight = (int) (srcHeight / ratio);
} else {
ratio = (double) srcHeight / newHeight;
destHeight = newHeight;
destWidth = (int) (srcWidth / ratio);
}
// 缩放的比例,缩放是很难按准备的比例进行缩放的,目前我只发现只能通过inSampleSize来进行缩放,其值表明缩放的倍数,SDK中建议其值是2的指数值
opts.inSampleSize = (int) ratio + 1;
// 设置大小
opts.outHeight = destHeight;
opts.outWidth = destWidth;
} else {
opts.inSampleSize = 1;
}
// 创建内存
opts.inJustDecodeBounds = false;
// 使图片不抖动
opts.inDither = false;
resizeBmp = BitmapFactory.decodeFileDescriptor(new FileInputStream(file.getPath()).getFD(), null, opts);
// resizeBmp = BitmapFactory.decodeFile(file.getPath(), opts);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return resizeBmp;
}
/**
* 描述:缩放图片,不压缩的缩放.
*
* @param bitmap the bitmap
* @param newWidth 新图片的宽
* @param newHeight 新图片的高
* @return Bitmap 新图片
*/
public static Bitmap scaleImg(Bitmap bitmap, int newWidth, int newHeight) {
if (bitmap == null) {
return null;
}
if (newHeight <= 0 || newWidth <= 0) {
return bitmap;
}
// 获得图片的宽高
int width = bitmap.getWidth();
int height = bitmap.getHeight();
if (width <= 0 || height <= 0) {
return null;
}
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的图片
Bitmap newBm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return newBm;
}
/**
* 描述:缩放图片.
*
* @param bitmap the bitmap
* @param scale 比例
* @return Bitmap 新图片
*/
public static Bitmap scaleImg(Bitmap bitmap, float scale) {
Bitmap resizeBmp = null;
try {
// 获取Bitmap资源的宽和高
int bmpW = bitmap.getWidth();
int bmpH = bitmap.getHeight();
// 注意这个Matirx是android.graphics底下的那个
Matrix mt = new Matrix();
// 设置缩放系数,分别为原来的0.8和0.8
mt.postScale(scale, scale);
resizeBmp = Bitmap.createBitmap(bitmap, 0, 0, bmpW, bmpH, mt, true);
} catch (Exception e) {
e.printStackTrace();
}
return resizeBmp;
}
/**
* 描述:裁剪图片.
*
* @param file File对象
* @param newWidth 新图片的宽
* @param newHeight 新图片的高
* @return Bitmap 新图片
*/
public static Bitmap cutImg(File file, int newWidth, int newHeight) {
Bitmap newBitmap = null;
try {
BitmapFactory.Options opts = new BitmapFactory.Options();
// 设置为true,decodeFile先不创建内存 只获取一些解码边界信息即图片大小信息
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(new FileInputStream(file.getPath()).getFD(), null, opts);
// BitmapFactory.decodeFile(file.getPath(), opts);
if (newWidth != -1 && newHeight != -1) {
// inSampleSize=2表示图片宽高都为原来的二分之一,即图片为原来的四分之一
// 缩放可以将像素点打薄,裁剪前将图片缩放一些
int srcWidth = opts.outWidth; // 获取图片的原始宽度
int srcHeight = opts.outHeight;// 获取图片原始高度
int destWidth = 0;
int destHeight = 0;
int cutSrcWidth = newWidth * 2;
int cutSrcHeight = newHeight * 2;
// 缩放的比例
double ratio = 0.0;
if (srcWidth < cutSrcWidth || srcHeight < cutSrcHeight) {
ratio = 0.0;
destWidth = srcWidth;
destHeight = srcHeight;
// 按比例计算缩放后的图片大小
} else if (srcWidth > srcHeight) {
ratio = (double) srcWidth / cutSrcWidth;
destWidth = cutSrcWidth;
destHeight = (int) (srcHeight / ratio);
} else {
ratio = (double) srcHeight / cutSrcHeight;
destHeight = cutSrcHeight;
destWidth = (int) (srcWidth / ratio);
}
// 缩放的比例,缩放是很难按准备的比例进行缩放的,目前我只发现只能通过inSampleSize来进行缩放,其值表明缩放的倍数,SDK中建议其值是2的指数值
opts.inSampleSize = (int) ratio + 1;
// 设置大小
opts.outHeight = destHeight;
opts.outWidth = destWidth;
} else {
opts.inSampleSize = 1;
}
// 创建内存
opts.inJustDecodeBounds = false;
// 使图片不抖动
opts.inDither = false;
// Bitmap resizeBmp = BitmapFactory.decodeFile(file.getPath(), opts);
Bitmap resizeBmp = BitmapFactory.decodeFileDescriptor(new FileInputStream(file.getPath()).getFD(), null, opts);
if (resizeBmp != null) {
newBitmap = cutImg(resizeBmp, newWidth, newHeight);
}
if (newBitmap != null) {
return newBitmap;
} else {
return resizeBmp;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return newBitmap;
} catch (IOException e) {
e.printStackTrace();
return newBitmap;
}
}
/**
* 描述:裁剪图片.
*
* @param bitmap the bitmap
* @param newWidth 新图片的宽
* @param newHeight 新图片的高
* @return Bitmap 新图片
*/
public static Bitmap cutImg(Bitmap bitmap, int newWidth, int newHeight) {
if (bitmap == null) {
return null;
}
Bitmap newBitmap = null;
if (newHeight <= 0 || newWidth <= 0) {
return bitmap;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
if (width <= 0 || height <= 0) {
return null;
}
int offsetX = 0;
int offsetY = 0;
if (width > newWidth) {
offsetX = (width - newWidth) / 2;
}
if (height > newHeight) {
offsetY = (height - newHeight) / 2;
}
newBitmap = Bitmap.createBitmap(bitmap, offsetX, offsetY, newWidth, newHeight);
return newBitmap;
}
/**
* Drawable转Bitmap.
*
* @param drawable 要转化的Drawable
* @return Bitmap
*/
public static Bitmap drawableToBitmap(Drawable drawable) {
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Config.ARGB_8888 : Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
drawable.draw(canvas);
return bitmap;
}
/**
* Drawable对象转换Bitmap对象.
*
* @param bitmap 要转化的Bitmap对象
* @return Drawable 转化完成的Drawable对象
*/
@SuppressWarnings("deprecation")
public static Drawable bitmapToDrawable(Bitmap bitmap) {
BitmapDrawable mBitmapDrawable = null;
try {
if (bitmap == null) {
return null;
}
mBitmapDrawable = new BitmapDrawable(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
return mBitmapDrawable;
}
/**
* 将Bitmap转换为byte[].
*
* @param bitmap the bitmap
* @param mCompressFormat 图片格式 Bitmap.CompressFormat.JPEG,CompressFormat.PNG
* @param needRecycle 是否需要回收
* @return byte[] 图片的byte[]
*/
public static byte[] bitmap2Bytes(Bitmap bitmap, Bitmap.CompressFormat mCompressFormat, final boolean needRecycle) {
byte[] result = null;
ByteArrayOutputStream output = null;
try {
output = new ByteArrayOutputStream();
bitmap.compress(mCompressFormat, 100, output);
result = output.toByteArray();
if (needRecycle) {
bitmap.recycle();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
return result;
}
/**
* 描述:将byte[]转换为Bitmap.
*
* @param b 图片格式的byte[]数组
* @return bitmap 得到的Bitmap
*/
public static Bitmap bytes2Bimap(byte[] b) {
Bitmap bitmap = null;
try {
if (b.length != 0) {
bitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
}
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
/**
* 将ImageView转换为Bitmap.
*
* @param view 要转换为bitmap的View
* @return byte[] 图片的byte[]
*/
public static Bitmap imageView2Bitmap(ImageView view) {
Bitmap bitmap = null;
try {
bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
/**
* 将View转换为Drawable.需要最上层布局为Linearlayout
*
* @param view 要转换为Drawable的View
* @return BitmapDrawable Drawable
*/
@SuppressWarnings("deprecation")
public static Drawable view2Drawable(View view) {
BitmapDrawable mBitmapDrawable = null;
try {
Bitmap newbmp = view2Bitmap(view);
if (newbmp != null) {
mBitmapDrawable = new BitmapDrawable(newbmp);
}
} catch (Exception e) {
e.printStackTrace();
}
return mBitmapDrawable;
}
/**
* 将View转换为Bitmap.需要最上层布局为Linearlayout
*
* @param view 要转换为bitmap的View
* @return byte[] 图片的byte[]
*/
public static Bitmap view2Bitmap(View view) {
Bitmap bitmap = null;
try {
if (view != null) {
view.setDrawingCacheEnabled(true);
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.buildDrawingCache();
bitmap = view.getDrawingCache();
}
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
/**
* 将View转换为byte[].
*
* @param view 要转换为byte[]的View
* @param compressFormat the compress format
* @return byte[] View图片的byte[]
*/
public static byte[] view2Bytes(View view, Bitmap.CompressFormat compressFormat) {
byte[] b = null;
try {
Bitmap bitmap = AbImageUtil.view2Bitmap(view);
b = AbImageUtil.bitmap2Bytes(bitmap, compressFormat, true);
} catch (Exception e) {
e.printStackTrace();
}
return b;
}
/**
* 描述:旋转Bitmap为一定的角度.
*
* @param bitmap the bitmap
* @param degrees the degrees
* @return the bitmap
*/
public static Bitmap rotateBitmap(Bitmap bitmap, float degrees) {
Bitmap mBitmap = null;
try {
Matrix m = new Matrix();
m.setRotate(degrees % 360);
mBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, false);
} catch (Exception e) {
e.printStackTrace();
}
return mBitmap;
}
/**
* 描述:旋转Bitmap为一定的角度并四周暗化处理.
*
* @param bitmap the bitmap
* @param degrees the degrees
* @return the bitmap
*/
public static Bitmap rotateBitmapTranslate(Bitmap bitmap, float degrees) {
Bitmap mBitmap = null;
int width;
int height;
try {
Matrix matrix = new Matrix();
if ((degrees / 90) % 2 != 0) {
width = bitmap.getWidth();
height = bitmap.getHeight();
} else {
width = bitmap.getHeight();
height = bitmap.getWidth();
}
int cx = width / 2;
int cy = height / 2;
matrix.preTranslate(-cx, -cy);
matrix.postRotate(degrees);
matrix.postTranslate(cx, cy);
} catch (Exception e) {
e.printStackTrace();
}
return mBitmap;
}
/**
* 转换图片转换成圆形.
*
* @param bitmap 传入Bitmap对象
* @return the bitmap
*/
public static Bitmap toRoundBitmap(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float roundPx;
float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
if (width <= height) {
roundPx = width / 2;
top = 0;
bottom = width;
left = 0;
right = width;
height = width;
dst_left = 0;
dst_top = 0;
dst_right = width;
dst_bottom = width;
} else {
roundPx = height / 2;
float clip = (width - height) / 2;
left = clip;
right = width - clip;
top = 0;
bottom = height;
width = height;
dst_left = 0;
dst_top = 0;
dst_right = height;
dst_bottom = height;
}
Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect src = new Rect((int) left, (int) top, (int) right, (int) bottom);
final Rect dst = new Rect((int) dst_left, (int) dst_top, (int) dst_right, (int) dst_bottom);
final RectF rectF = new RectF(dst);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, src, dst, paint);
return output;
}
public static byte[] imagePathToByte(String path) {
byte[] data = null;
FileInputStream input = null;
try {
input = new FileInputStream(new File(path));
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int numBytesRead = 0;
while ((numBytesRead = input.read(buf)) != -1) {
output.write(buf, 0, numBytesRead);
}
data = output.toByteArray();
output.close();
input.close();
} catch (FileNotFoundException ex1) {
ex1.printStackTrace();
} catch (IOException ex1) {
ex1.printStackTrace();
}
return data;
}
/**
* @param bitmap 原图
* @param edgeLength 希望得到的正方形部分的边长
* @return 缩放截取正中部分后的位图。
*/
public static Bitmap centerSquareScaleBitmap(Bitmap bitmap, int edgeLength) {
if (null == bitmap || edgeLength <= 0) {
return null;
}
Bitmap result = bitmap;
int widthOrg = bitmap.getWidth();
int heightOrg = bitmap.getHeight();
if (widthOrg > edgeLength && heightOrg > edgeLength) {
// 压缩到一个最小长度是edgeLength的bitmap
int longerEdge = edgeLength * Math.max(widthOrg, heightOrg) / Math.min(widthOrg, heightOrg);
int scaledWidth = widthOrg > heightOrg ? longerEdge : edgeLength;
int scaledHeight = widthOrg > heightOrg ? edgeLength : longerEdge;
Bitmap scaledBitmap;
try {
scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
} catch (Exception e) {
return null;
}
// 从图中截取正中间的正方形部分。
int xTopLeft = (scaledWidth - edgeLength) / 2;
int yTopLeft = (scaledHeight - edgeLength) / 2;
try {
result = Bitmap.createBitmap(scaledBitmap, xTopLeft, yTopLeft, edgeLength, edgeLength);
scaledBitmap.recycle();
} catch (Exception e) {
return null;
}
}
return result;
}
/**
* @param bitmap 原图
* @param edgeLength 希望得到的正方形部分的边长
* @return 缩放截取上面部分后的位图。
*/
public static Bitmap topSquareScaleBitmap(Bitmap bitmap, int edgeLength) {
if (null == bitmap || edgeLength <= 0) {
return null;
}
Bitmap result = bitmap;
int widthOrg = bitmap.getWidth();
int heightOrg = bitmap.getHeight();
if (widthOrg > edgeLength && heightOrg > edgeLength) {
// 压缩到一个最小长度是edgeLength的bitmap
int longerEdge = edgeLength * Math.max(widthOrg, heightOrg) / Math.min(widthOrg, heightOrg);
int scaledWidth = widthOrg > heightOrg ? longerEdge : edgeLength;
int scaledHeight = widthOrg > heightOrg ? edgeLength : longerEdge;
Bitmap scaledBitmap;
try {
scaledBitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
} catch (Exception e) {
return null;
}
// 从图中截取正中间的正方形部分。
int xTopLeft = (scaledWidth - edgeLength) / 2;
// int yTopLeft = (scaledHeight - edgeLength) / 2;
int yTopLeft = 0;
try {
result = Bitmap.createBitmap(scaledBitmap, xTopLeft, yTopLeft, edgeLength, edgeLength);
scaledBitmap.recycle();
} catch (Exception e) {
return null;
}
}
return result;
}
/**
* 转换Resources图片转换成Bitmap.
*/
public static Bitmap ResourcesToBitmap(Resources resId) {
Bitmap bmp = BitmapFactory.decodeResource(resId, R.mipmap.ic_launcher);
return bmp;
}
/**
* bitmap转为base64
* @param bitmap
* @return
*/
public static String bitmapToBase64(Bitmap bitmap) {
String result = null;
ByteArrayOutputStream baos = null;
try {
if (bitmap != null) {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result ="data:image/jpg;base64," + Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* base64转为bitmap
* @param base64Data
* @return
*/
public static Bitmap base64ToBitmap(String base64Data) {
byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
/**
* bitmap转成string
*
* @param bitmap
* @return
*/
public static String bitmapToString(Bitmap bitmap)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] appicon = baos.toByteArray();// 转为byte数组
return Base64.encodeToString(appicon, Base64.DEFAULT);
}
/**
* string转成bitmap
*
* @param st
*/
public static Bitmap stringToBitmap(String st)
{
Bitmap bitmap = null;
try
{
byte[] bitmapArray;
bitmapArray = Base64.decode(st, Base64.DEFAULT);
bitmap =
BitmapFactory.decodeByteArray(bitmapArray, 0,
bitmapArray.length);
return bitmap;
}
catch (Exception e)
{
return null;
}
}
}
1.3. 图片压缩(质量压缩和尺寸压缩)&Bitmap转成字符串上传
图片压缩的方法大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩);质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成缩略图。
1.3.1. android图片压缩总结
总结来看,图片有三种存在形式:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap,所谓的质量压缩,它其实只能实现对file的影响,你可以把一个file转成bitmap再转成file,或者直接将一个bitmap转成file时,这个最终的file是被压缩过的,但是中间的bitmap并没有被压缩(或者说几乎没有被压缩,我不确定),因为bigmap在内存中的大小是按像素计算的,也就是width * height,对于质量压缩,并不会改变图片的像素,所以就算质量被压缩了,但是bitmap在内存的占有率还是没变小,但你做成file时,它确实变小了;
而尺寸压缩由于是减小了图片的像素,所以它直接对bitmap产生了影响,当然最终的file也是相对的变小了;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
/**
* Image compress factory class
*
* @author
*
*/
public class ImageFactory {
/**
* Get bitmap from specified image path
*
* @param imgPath
* @return
*/
public Bitmap getBitmap(String imgPath) {
// Get bitmap through image path
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = false;
newOpts.inPurgeable = true;
newOpts.inInputShareable = true;
// Do not compress
newOpts.inSampleSize = 1;
newOpts.inPreferredConfig = Config.RGB_565;
return BitmapFactory.decodeFile(imgPath, newOpts);
}
/**
* Store bitmap into specified image path
*
* @param bitmap
* @param outPath
* @throws FileNotFoundException
*/
public void storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException {
FileOutputStream os = new FileOutputStream(outPath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
}
/**
* Compress image by pixel, this will modify image width/height.
* Used to get thumbnail
*
* @param imgPath image path
* @param pixelW target pixel of width
* @param pixelH target pixel of height
* @return
*/
public Bitmap ratio(String imgPath, float pixelW, float pixelH) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
// 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容
newOpts.inJustDecodeBounds = true;
newOpts.inPreferredConfig = Config.RGB_565;
// Get bitmap info, but notice that bitmap is null now
Bitmap bitmap = BitmapFactory.decodeFile(imgPath,newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
// 想要缩放的目标尺寸
float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了
float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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(imgPath, newOpts);
// 压缩好比例大小后再进行质量压缩
// return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除
return bitmap;
}
/**
* Compress image by size, this will modify image width/height.
* Used to get thumbnail
*
* @param image
* @param pixelW target pixel of width
* @param pixelH target pixel of height
* @return
*/
public Bitmap ratio(Bitmap image, float pixelW, float pixelH) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, os);
if( os.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
os.reset();//重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 50, os);//这里压缩50%,把压缩后的数据存放到baos中
}
ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
BitmapFactory.Options newOpts = new BitmapFactory.Options();
//开始读入图片,此时把options.inJustDecodeBounds 设回true了
newOpts.inJustDecodeBounds = true;
newOpts.inPreferredConfig = Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了
float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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了
is = new ByteArrayInputStream(os.toByteArray());
bitmap = BitmapFactory.decodeStream(is, null, newOpts);
//压缩好比例大小后再进行质量压缩
// return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除
return bitmap;
}
/**
* Compress by quality, and generate image to the path specified
*
* @param image
* @param outPath
* @param maxSize target will be compressed to be smaller than this size.(kb)
* @throws IOException
*/
public void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
// scale
int options = 100;
// Store the bitmap into output stream(no compress)
image.compress(Bitmap.CompressFormat.JPEG, options, os);
// Compress by loop
while ( os.toByteArray().length / 1024 > maxSize) {
// Clean up os
os.reset();
// interval 10
options -= 10;
image.compress(Bitmap.CompressFormat.JPEG, options, os);
}
// Generate compressed image file
FileOutputStream fos = new FileOutputStream(outPath);
fos.write(os.toByteArray());
fos.flush();
fos.close();
}
/**
* Compress by quality, and generate image to the path specified
*
* @param imgPath
* @param outPath
* @param maxSize target will be compressed to be smaller than this size.(kb)
* @param needsDelete Whether delete original file after compress
* @throws IOException
*/
public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {
compressAndGenImage(getBitmap(imgPath), outPath, maxSize);
// Delete original file
if (needsDelete) {
File file = new File (imgPath);
if (file.exists()) {
file.delete();
}
}
}
/**
* Ratio and generate thumb to the path specified
*
* @param image
* @param outPath
* @param pixelW target pixel of width
* @param pixelH target pixel of height
* @throws FileNotFoundException
*/
public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException {
Bitmap bitmap = ratio(image, pixelW, pixelH);
storeImage( bitmap, outPath);
}
/**
* Ratio and generate thumb to the path specified
*
* @param image
* @param outPath
* @param pixelW target pixel of width
* @param pixelH target pixel of height
* @param needsDelete Whether delete original file after compress
* @throws FileNotFoundException
*/
public void ratioAndGenThumb(String imgPath, String outPath, float pixelW, float pixelH, boolean needsDelete) throws FileNotFoundException {
Bitmap bitmap = ratio(imgPath, pixelW, pixelH);
storeImage( bitmap, outPath);
// Delete original file
if (needsDelete) {
File file = new File (imgPath);
if (file.exists()) {
file.delete();
}
}
}
}
1.3.2. 图片质量压缩
/**
* 质量压缩方法
*
* @param image
* @return
*/
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 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
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;
}
1.3.3. 按比例大小压缩 (路径获取图片)
/**
* 图片按比例大小压缩方法
*
* @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);// 压缩好比例大小后再进行质量压缩
}
1.3.4. 按比例大小压缩 (Bitmap)
/**
* 图片按比例大小压缩方法
*
* @param image (根据Bitmap图片压缩)
* @return
*/
public static Bitmap compressScale(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
// 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
if (baos.toByteArray().length / 1024 > 1024) {
baos.reset();// 重置baos即清空baos
image.compress(Bitmap.CompressFormat.JPEG, 80, 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;
Log.i(TAG, w + "---------------" + h);
// 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
// float hh = 800f;// 这里设置高度为800f
// float ww = 480f;// 这里设置宽度为480f
float hh = 512f;
float ww = 512f;
// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
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;
}
1.4. 按照图片尺寸压缩
public static void compressPicture(String srcPath, String desPath) {
FileOutputStream fos = null;
BitmapFactory.Options op = new BitmapFactory.Options();
// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
op.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, op);
op.inJustDecodeBounds = false;
// 缩放图片的尺寸
float w = op.outWidth;
float h = op.outHeight;
float hh = 1024f;//
float ww = 1024f;//
// 最长宽度或高度1024
float be = 1.0f;
if (w > h && w > ww) {
be = (float) (w / ww);
} else if (w < h && h > hh) {
be = (float) (h / hh);
}
if (be <= 0) {
be = 1.0f;
}
op.inSampleSize = (int) be;// 设置缩放比例,这个数字越大,图片大小越小.
// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
bitmap = BitmapFactory.decodeFile(srcPath, op);
int desWidth = (int) (w / be);
int desHeight = (int) (h / be);
bitmap = Bitmap.createScaledBitmap(bitmap, desWidth, desHeight, true);
try {
fos = new FileOutputStream(desPath);
if (bitmap != null) {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
需要注意两个问题:
(1)调用getDrawingCache()前先要测量,否则的话得到的bitmap为null,这个我在OnCreate()、OnStart()、OnResume()方法里都试验过。
(2)当调用bitmap.compress(CompressFormat.JPEG, 100, fos);保存为图片时发现图片背景为黑色,如下图:
这时只需要改成用png保存就可以了,bitmap.compress(CompressFormat.PNG, 100, fos);,如下图:
在实际开发中,有时候我们需求将文件转换为字符串,然后作为参数进行上传。
1.4.1. 必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import java.io.ByteArrayOutputStream;
/**
*
*
* 功能描述:Android开发之常用必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式
*/
public class BitmapAndStringUtils {
/**
* 图片转成string
*
* @param bitmap
* @return
*/
public static String convertIconToString(Bitmap bitmap)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] appicon = baos.toByteArray();// 转为byte数组
return Base64.encodeToString(appicon, Base64.DEFAULT);
}
/**
* string转成bitmap
*
* @param st
*/
public static Bitmap convertStringToIcon(String st)
{
// OutputStream out;
Bitmap bitmap = null;
try
{
// out = new FileOutputStream("/sdcard/aa.jpg");
byte[] bitmapArray;
bitmapArray = Base64.decode(st, Base64.DEFAULT);
bitmap =
BitmapFactory.decodeByteArray(bitmapArray, 0,
bitmapArray.length);
// bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
return bitmap;
}
catch (Exception e)
{
return null;
}
}
}
如果你的图片是File文件,可以用下面代码:
/**
* 图片文件转换为指定编码的字符串
*
* @param imgFile 图片文件
*/
public static String file2String(File imgFile) {
InputStream in = null;
byte[] data = null;
//读取图片字节数组
try{
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e){
e.printStackTrace();
}
//对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
String result = encoder.encode(data);
return result;//返回Base64编码过的字节数组字符串
}
1.5. 图片网址url转化为bitmap
1.5.1. 方法一 通过 HttpURLConnection 请求
要使用一个线程去访问,因为是网络请求,这是一个一步请求,不能直接返回获取,要不然永远为null,在这里得到BitMap之后记得使用Hanlder或者EventBus传回主线程,不过现在加载图片都是用框架了,很少有转化为Bitmap的需求。
/**
* 通过 网络图片 url 获取图片 Bitmap
* @param photoUrl 网络图片 url
*/
private void requestWebPhotoBitmap(String photoUrl) {
new Thread(() -> {
HttpURLConnection connection = null;
try {
URL bitmapUrl = new URL(photoUrl);
connection = (HttpURLConnection) bitmapUrl.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
// 判断是否请求成功
if (connection.getResponseCode() == 200) {
Message hintMessage = new Message();
hintMessage.what = HANDLER_START_DOWNLOAD;
hintHandler.sendMessage(hintMessage);
InputStream inputStream = connection.getInputStream();
imgBitmap = BitmapFactory.decodeStream(inputStream);
Message message = showHandler.obtainMessage();
showHandler.sendMessage(message);
} else {
Message hintMessage = new Message();
hintMessage.what = HANDLER_NET_ERROR;
hintHandler.sendMessage(hintMessage);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) connection.disconnect();
}
}).start();
}
/**
* 设置提示
*/
private final Handler hintHandler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
if(msg.what == HANDLER_START_DOWNLOAD)
Toast.makeText(MainActivity.this, "获取图片中,请稍等", Toast.LENGTH_SHORT).show();
else if(msg.what == HANDLER_NET_ERROR)
Toast.makeText(MainActivity.this, "网络错误,请重试", Toast.LENGTH_SHORT).show();
}
};
/**
* 展示图片
*/
@SuppressLint("HandlerLeak")
private final Handler showHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
ivPhoto.setImageBitmap(imgBitmap); //填充控件
}
};
1.5.2. 方法二 通过 Glide
1.5.2.1. java
/**
* 获取 网络图片 Bitmap
* @param imgUrl 网络图片url
*/
private void requestWebPhotoBitmap(String imgUrl) {
Toast.makeText(MainActivity.this, "获取图片中,请稍等", Toast.LENGTH_SHORT).show();
Glide.with(MainActivity.this).asBitmap().load(imgUrl).into(new CustomTarget<Bitmap>() {
@SuppressLint("ClickableViewAccessibility")
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
imgBitmap = resource;
ivPhoto.setImageBitmap(imgBitmap)
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
1.5.2.2. kotlin
Glide.with(this).asBitmap()
.load(paramBean.userImg).into(object : CustomTarget<Bitmap?>() {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap?>?) {
val bitmap = resource
}
override fun onLoadCleared(placeholder: Drawable?) {}
})
1.5.3. 调用
private Bitmap imgBitmap = null;
private ImageView ivPhoto;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivPhoto = (ImageView) findViewById(R.id.photo);
String imgUrl = "https://w.wallhaven.cn-l63x6k.png";
requestWebPhotoBitmap(imgUrl);
}
1.6. base64编码转化成图片
1.6.1.base64编码转化成图片
(1)类似base64流的图片解析并展示:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcH Bw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAPUAooDAREAAhEBAxEB/8QAHQAAAQUBAQEBAAAAAAAAAAAAAgABAwQFBgcICf/EAE0QAAEDAgQEAwUGBAUCBAQEBwEAAgMEEQUSITEGQVFhEyJxBxQygZEjQqGxwfAVUtHhJDNDYnII8RZTgpIlNETCF2Oy0iZUc4OTouL/xAAaAQEBAQEBAQEAAAAAAAAAAAAAAQIDBAUG/8QAMxEBAQACAgICAgIBAwMEAgIDAAECEQMhEjEEQRNRIjJhBRRxQoGRIzNSsQahFtEVQ+H/2gAMAwEAAhEDEQA/APSwPovG+kKyaDgKhwinsgIBRRs3Cs9oEg3XSMlZVD2QKyGj2QPZArIFZEIhA1rJoJNKSaQrJoMRzVQ1lNKVk0FZUNZQK11QxCIrSDzlVAEISGITsMQnYaybU1imwkCtooHsgYhSQMQgVkCRSVQ1t0DW0QK3ZA1kNlYKhH1SBBpJ0CJY0W55cvlsALLWMKevj8RjWnQjZay7SM59O9vK/oudioiLaWU0prIgbIGIQMRqmgxCnYYpIBsm1MQUE1INJP8AiVqJVQhQLkiBKKYogCiBKKY9VAxQoCiGKACgYoBKAToEKEoBOpVoAogHKVYByJQOCbIBQ09NAXN6D2QPZFOApsPZNqIBEGweZWAea6sEgcIFZArIHQKyBWKBW0V2hWU2piFU0Vk2pWQLom00YoGsh2QQJArIGQVn/EqyAhUNZRTdkQkU1kCsVE0ayKQ0QKyBWTYVlIGtoqGI+aBEJAypsipo2VlUpiLa8kW09Nknfljka4jcApqm40oKUNFyFuYokkkigb5it9RGfNUulkuBYDZc7n2ujtl6pvadnc2N+4CuoIn0oOrHfVTxXaCSF7NwVnVhURHVZ2gVVMUDFQDzRTFEWaSN9nafENFqFVJo3RvLXizgpQCiAOiqhKBiFNpoJQCUAlECVFMVUCUDFAJQCUAlABCATsgjJQ9AKIBymwCNaen2XN22cBA4sgSNCCFOAoDYNVqIGy6MHsgeyBIEgcboG5oHQKyBKhEIGsmkJNKShsrKkMQiGtqi7KyBWRAkIqvIPMqyCybOjWTaUJCKVkoSWmi9E0aKylCsgVkDWQN+KBdkCAQNZA1lTRFDY4IzI42F7C5CsmwDrPOVo3NiCr4/Q4vFoazCONaKehe4QzOAkJWjIySBigRQMgSBggSBuSBFChOyJs1yro2/9k=
(2)将Base64数据流转换为可展示的Bitmap
byte[] decode = Base64.decode(firstInfo.img.img.split(",")[1], Base64.DEFAULT);
Bitmap bitmap = BitmapFactory.decodeByteArray(decode, 0, decode.length);
ivCode.setImageBitmap(bitmap);
注意:含有“data:image/*;base64”的头的编码,在decode的时候就要去掉,否则是无法还原成功的。
去掉头部
firstInfo.img.img.split(",")[1]
再将bitmap转化成图片!
1.6.2.将Base64转成Bitmap
public static Bitmap base64ToBitmap(String base64Data) {
byte[] bytes = Base64.decode(base64Data.split(",")[1], Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
更多推荐
所有评论(0)