欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android bitmap 一些常用用法

程序员文章站 2024-01-22 20:05:16
...

说到Bitmap,Android 的朋友肯定很熟悉了,下面是我对bitmap一些常用方法的总结。之后会陆续更新。

圆角bitmap


    /**
     * 
     * @param source 
     * @param radius 圆角半径
     * @return
     */

public static Bitmap getRoundCornerBitmap(Bitmap source, float radius) {
        if (source == null) return null;
        if(radius <= 0){
            return source;
        }
        Bitmap result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(result);
        Paint paint = new Paint();
        paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
        paint.setAntiAlias(true);
        RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
        canvas.drawRoundRect(rectF, radius, radius, paint);
        return result;
    }

读取Asset图片

public static Bitmap getImageFromAssetsFile(String fileName, Context context){
        Bitmap image = null;
        AssetManager am = context.getResources().getAssets();
        InputStream is = null;
        try {
            is = am.open(fileName);
            image = BitmapFactory.decodeStream(is);
            is.close();
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return image;
    }

缩放图片

 public static Bitmap scaleBitmap(Bitmap bitmap, int dstWidth, int dstHeight) {
        if(bitmap == null){
            return null;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        float scaleWidth = ((float) dstWidth) / width;
        float scaleHeight = ((float) dstHeight) / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap newbm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
        return newbm;
    }

读取图片
sampleSize 是指采样率,比如读取原图,sample为1,比如你要读取的图片宽高是原图的1/2,则sampleSize=2,合理使用sampleSize能有效节省内存,比如原图宽高为1080x1920, 而实际只需要显示在108x192的imageview上,最暴力的方法,直接读取原图,但这样很容易oom,或者读取原图,然后放缩到指定尺寸,这个过程也会消耗大量内存,而按照下面的方法,只需要设置sampleSize=10就可以了。

public static Bitmap getBitmapWithPath(String path, int sampleSize){
        if(TextUtils.isEmpty(path)){
            return null;
        }
        if(sampleSize <= 0){
            sampleSize = 1;
        }
        File file = new File(path);
        if(file.exists() && file.isFile()) {
            BitmapFactory.Options boundOptions = new BitmapFactory.Options();
            boundOptions.inJustDecodeBounds = false;
            boundOptions.inSampleSize = sampleSize;
            boundOptions.inDither = true;
            boundOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
            return BitmapFactory.decodeFile(path, boundOptions);
        }
        return null;
    }

所以读取一个图片的时候最好的流程这样:读取图片大小(见下述代码)–>计算缩放比例–>读取指定大小的图片(见上述代码)

读取图片大小

 public static Size getBitmapBoundWithPath(String path){
        InputStream input = null;
        try {
            input = new FileInputStream(path);
            if(input == null){
                return null;
            }
            BitmapFactory.Options boundOptions = new BitmapFactory.Options();
            boundOptions.inJustDecodeBounds = true;
            boundOptions.inSampleSize = 1;
            BitmapFactory.decodeStream(input, null, boundOptions);//只取宽高,节省内存
            input.close();
            return new Size(boundOptions.outWidth, boundOptions.outHeight);
        } catch (Exception e) {
            Log.d(TAG, "exception:" + e.getMessage());
            return null;
        }finally {
            if(input != null){
                try {
                    input.close();
                } catch (IOException e) {
                    Log.d(TAG, "exception:" + e.getMessage());
                    return null;
                }
            }
        }
    }

从视频中获取帧
下面的代码并不能兼容所有的Android机器,比如华为P10用下面方法截帧是不靠谱的。

/**
     * 
     * @param path
     * @param time 毫秒
     * @return
     */
 public static Bitmap getFrameFromVideo(String path, long time){
        try {
            MediaMetadataRetriever retriever = new MediaMetadataRetriever();
            retriever.setDataSource(path);
            String durationStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
            long duration = Integer.valueOf(durationStr);
            if(time > duration || time < 0){
                return null;
            }
            Bitmap bitmap = retriever.getFrameAtTime(time * 1000);
            return bitmap;
        }catch (Exception e){
            return null;
        }
    }