Advertisement

Android图片压缩,Drawable和Bitmap转换,bitmap和base64转换,网络资源图片转化成bitmap,File-Base64-MultipartFile之间相互转换

阅读量:

1. Android图片压缩,Drawable和Bitmap转换,bitmap和base64转换,网络资源图片转化成bitmap,File-Base64-MultipartFile之间相互转换

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 );
    
    
    javascript
    
    

或者

复制代码
    Drawable drawable = getResources().getDrawable(R.drawable.ic);
    
    
    javascript
    
    

或者

复制代码
    iv.setImageResource(R.drawable.ic_launcher);
    
    
    javascript
    
    

获取路径下的图片资源:

复制代码
    String fileName = "/data/data/com.test/aa.png; 
    Bitmap bm = BitmapFactory.decodeFile(fileName); 
    iv.setImageBitmap(bm); //占用内存
    
    
    javascript
    
    

1.1.2. Drawable转换成Bitmap

第一种:

复制代码
    BitmapDrawable bd = (BitmapDrawable) drawable;
    Bitmap bm= bd.getBitmap();
    
    
    javascript
    
    

第二种:

复制代码
    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;   
    }   
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/p5zs3XDcZo4bgWkNhTKCUFRH1uMG.png)

1.1.3. Bitmap转换成Drawable

第一种:

复制代码
    Drawable drawable = new BitmapDrawable(bitmap); 
    
    
    javascript
    
    

第二种:

复制代码
    BitmapDrawable bd= new BitmapDrawable(getResource(), bm);    
    
    
    javascript
    
    

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);
    }
    }
    
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/fC9iSjBLW73b28usoUywAKHcneF1.png)

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;
        }
    }
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/RX8MVoWp3ZeDzQPbwmL6clTCd0iU.png)

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();
    					}
    				}
    	}
    	
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/d1NS5yqhIXczKik8uvUs936LgwRr.png)

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;
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/arHUqS8lyTXQ13dMBs6uJFV4xDRf.png)

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);// 压缩好比例大小后再进行质量压缩
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/YAcVlJt1Sdas39DqQkLweIP6Bf0n.png)

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;
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/VD4p9Q3MW16jzUiFXKCaA0PghysR.png)

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();
    		}
    	}
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/naEsch3G1uRKxdHOJfbBwpCQ8vmM.png)

需要注意两个问题:
(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;
        }
    }
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/EjaC2sR9rnyb73z0gKxBvQhuL4cN.png)

如果你的图片是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编码过的字节数组字符串
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/drVETjgn2fyFa79G3mALb8vWRDkw.png)

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); //填充控件
        }
    };
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/WwYTznPRcXt2SjLKoI5CeDbqiMfE.png)

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) {
     
            }
        });
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/nBMGhjUTWOfXCKEt5cmaLIF6e8DQ.png)
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?) {}
                    })
    
    
    javascript
    
    

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);
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/SFTPlUKuivXRsrMxwG6Zek3VIzLh.png)

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=
    
    
    java
    
    

(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);
    
    
    java
    
    

注意:含有“data:image/*;base64”的头的编码,在decode的时候就要去掉,否则是无法还原成功的。
去掉头部

复制代码
    firstInfo.img.img.split(",")[1]
    
    
    java
    
    

再将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);
    }
    
    
    java
    
    

1.7. File、Base64、MultipartFile之间相互转换

1.7.1. 文件转base64字符串

复制代码
    /** * file转换为base64
     * 注意:这里转换为base64后,是不包含文件head头的
     */
    public static String fileToBase64(File file) {
    Base64.Encoder base64 = Base64.getEncoder();
    String base64Str = null;
    try (FileInputStream fis = new FileInputStream(file);
         ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
        byte[] b = new byte[1024];
        int n;
        while ((n = fis.read(b)) != -1) {
            bos.write(b, 0, n);
        }
        base64Str = base64.encodeToString(bos.toByteArray());
    } catch (IOException e) {
        e.printStackTrace();
    }
    return base64Str;
    }
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/XqfZ58CYzpPmaoFkwQT2tJHeh4Er.png)

1.7.2. base64字符串转文件

复制代码
    /** * base64转化为file,并保存到指定路径下
     */
    public static void base64ToFile(String base, String path) {
    if (StringUtils.isBlank(base)) {
        return;
    }
    Base64.Decoder decoder = Base64.getDecoder();
    try (OutputStream out = new FileOutputStream(path)) {
        byte[] bytes = decoder.decode(base);
        for (int i = 0; i < bytes.length; ++i) {
            if (bytes[i] < 0) {
                bytes[i] += 256;
            }
        }
        out.write(bytes);
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
    
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/GQL1kFrCYAePSg8DvWBOEJcdxmfX.png)

1.7.3. base64转化为file流

复制代码
    /** * base64转化为file流
     */
    public static File base64ToFile(String base64) {
    if (base64 == null || "".equals(base64)) {
        return null;
    }
    byte[] buff = Base64.getDecoder().decode(base64);
    
    File file;
    try {
        file = File.createTempFile("tmp", null);
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
    try (FileOutputStream out = new FileOutputStream(file)) {
        out.write(buff);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return file;
    }
    
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/Wd8fP1HqR4kVXsvt9JoFKzZxMyCc.png)

1.7.4. base64转MultipartFile

复制代码
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.*;
    import java.util.Base64;
    
    /** * @author 笑小枫
     */
    public class Base64DecodedMultipartFile implements MultipartFile {
    private final byte[] imgContent;
    private final String header;
    private final String fileName;
    
    public Base64DecodedMultipartFile(byte[] imgContent, String header, String fileName) {
        this.imgContent = imgContent;
        this.header = header.split(";")[0];
        this.fileName = fileName;
    }
    
    @Override
    public String getName() {
        return fileName + "." + header.split("/")[1];
    }
    
    @Override
    public String getOriginalFilename() {
        return fileName + "." + header.split("/")[1];
    }
    
    @Override
    public String getContentType() {
        return header.split(":")[1];
    }
    
    @Override
    public boolean isEmpty() {
        return imgContent == null || imgContent.length == 0;
    }
    
    @Override
    public long getSize() {
        return imgContent.length;
    }
    
    @Override
    public byte[] getBytes() {
        return imgContent;
    }
    
    @Override
    public InputStream getInputStream() {
        return new ByteArrayInputStream(imgContent);
    }
    
    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        try (FileOutputStream fos = new FileOutputStream(dest)) {
            fos.write(imgContent);
        }
    }
    
    /** * base64转multipartFile
     **/
    public static MultipartFile base64Convert(String base64, String header, String fileName) {
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] b = decoder.decode(base64);
        //取索引为1的元素进行处理
        for (int i = 0; i < b.length; ++i) {
            if (b[i] < 0) {
                b[i] += 256;
            }
        }
        // 处理过后的数据通过Base64DecodeMultipartFile转换为MultipartFile对象
        return new Base64DecodedMultipartFile(b, header, fileName);
    }
    }
    
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/BXlbAVtTc1quaUKwsgrnMyx9O2Di.png)

1.7.5. bitmap转Base64、base64转Bitmap

复制代码
    ublic class PatrolHelper {
    /** * bitmap转Base64
     */
    public static String bitmapToBase64(Bitmap bitmap) {
        try {
            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;
        } catch (Exception e) {
            Log.e("szyj_TestListA_", "Exception相似度:" +  e.getMessage());
        }
        return null;
    }
    /** * base64转Bitmap
     */
    public static Bitmap base64ToBitmap(String base64) {
        try {
            byte[] decode = Base64.decode(base64
                    .split(",")[1], Base64.DEFAULT);
            Bitmap bitmap = BitmapFactory.decodeByteArray(decode,
                    0, decode.length);
            return bitmap;
        } catch (Exception e) {
        }
        return null;
    }
    }
    
    
    
    javascript
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/HAvSk3PXiJusdf5o7Bpg9aODKneL.png)

全部评论 (0)

还没有任何评论哟~