安卓开发(四)收藏的轮子——图片相关


layout: post
title: 安卓开发(四)收藏的轮子——图片相关
description: 安卓开发(四)收藏的轮子——图片相关
tag: 安卓


界面布局

沉浸式标题栏

沉浸式标题栏

在这里插入图片描述

一个可以使得屏幕铺满顶部状态栏的方法:

    /**
     * 通过设置全屏,设置状态栏透明
     *
     * @param activity
     */
    public static void fullScreen(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色
                Window window = activity.getWindow();
                View decorView = window.getDecorView();
                //两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间
                int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
                decorView.setSystemUiVisibility(option);
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.setStatusBarColor(Color.TRANSPARENT);
                //导航栏颜色也可以正常设置
//                window.setNavigationBarColor(Color.TRANSPARENT);
            } else {
                Window window = activity.getWindow();
                WindowManager.LayoutParams attributes = window.getAttributes();
                int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
                int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
                attributes.flags |= flagTranslucentStatus;
//                attributes.flags |= flagTranslucentNavigation;
                window.setAttributes(attributes);
            }
        }
    }

在manifest中指定app的主题style:
在这里插入图片描述

style中的下边两个属性分别表示标题栏背景色和状态栏背景色,两者设为一致既可实现沉浸式效果,铺满全屏。

在这里插入图片描述

走马灯轮播图

引入依赖:implementation 'com.youth.banner:banner:1.4.10'
xml:

                <com.youth.banner.Banner
                    android:layout_marginLeft="@dimen/dp_10"
                    android:layout_marginRight="@dimen/dp_10"
                    android:layout_marginTop="@dimen/dp_10" 
                    android:id="@+id/banner"
                    android:layout_width="match_parent"
                    android:layout_height="150dp" >

activity中,先获取到banner组件对象,然后初始化:
主要是构建imgePath列表和标题列表,然后banner.setImages设置图片,banner.setTittles设置标题。
加载具体的实现是通过加载器Myloader,通过glide加载图片到imageview中。然后可以重写OnBannerClick,设置轮播图点击反馈事件。

    private void initBanner() {
        List<User> friends = application.getFriendList();
        //放图片地址的集合
        list_path = new ArrayList<>();
        //放标题的集合
        list_title = new ArrayList<>();
        if (friends!=null) {
            for (int i = 0; i < friends.size(); i++) {
                list_path.add(friends.get(i).getAvatar());
                list_title.add(friends.get(i).getFullName());
            }
        }
        list_title.add("更多");
        list_path.add("https://img-blog.csdnimg.cn/9a6ae33e401543589b3f953a87166746.png");
        //设置内置样式,共有六种可以点入方法内逐一体验使用。
        banner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE);
        //设置图片加载器,图片加载器在下方
        banner.setImageLoader(new MyLoader());
        //设置图片网址或地址的集合
        banner.setImages(list_path);
        //设置轮播的动画效果,内含多种特效,可点入方法内查找后内逐一体验
        banner.setBannerAnimation(Transformer.Default);
        //设置轮播图的标题集合
        banner.setBannerTitles(list_title);
        //设置轮播间隔时间
        banner.setDelayTime(3000);
        //设置是否为自动轮播,默认是“是”。
        banner.isAutoPlay(true);
        //设置指示器的位置,小点点,左中右。
        banner.setIndicatorGravity(BannerConfig.CENTER)
                //以上内容都可写成链式布局,这是轮播图的监听。比较重要。方法在下面。
                .setOnBannerListener(this)
                //必须最后调用的方法,启动轮播图。
                .start();
    }
    //自定义的图片加载器
    private class MyLoader extends ImageLoader {
        @Override
        public void displayImage(Context context, Object path, ImageView imageView) {
            Glide.with(context).load((String) path).into(imageView);
        }
    }

    @Override
    public void OnBannerClick(int position) {
        Log.i("tag", "你点了第"+position+"张轮播图");
    }

图标、图片处理、头像相关

下载图标
一些依赖:

    implementation 'com.github.bumptech.glide:glide:4.11.0' // 图片加载
    implementation 'com.github.chrisbanes:PhotoView:2.3.0'    // 大图图片显示,拖拉放大
    implementation 'top.zibin:Luban:1.1.8'  // 图片压缩类
    implementation 'com.github.Othershe:CombineBitmap:1.0.5' //bitmap合成,仿微信群头像
    implementation 'com.githang:clipimageview:0.1' // 头像剪裁
    implementation 'cjt.library.wheel:camera:1.1.9' // 调用相机拍照和录制视频

ImageUtils

包含在Bitmap中绘制文字水印;从网络上下载图片Bitmap保存;取出视频的第一帧转为Bitmap构建视频缩略图;旋转Bitmap指定angle;Glide加载头像的封装;view转bitmap显示自定义图标。

package com.beidouapp.model.utils;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.beidouapp.Config;
import com.beidouapp.R;
import com.beidouapp.ui.DemoApplication;
import com.beidouapp.ui.Setting.ActivityUser;
import com.beidouapp.ui.Setting.ClipAvatar;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutionException;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Response;
import wseemann.media.FFmpegMediaMetadataRetriever;

public class ImageUtil {
    /**
     * 设置水印图片在左上角
     *
     * @param context     上下文
     * @param src
     * @param watermark
     * @param paddingLeft
     * @param paddingTop
     * @return
     */
    public static Bitmap createWaterMaskLeftTop(Context context, Bitmap src, Bitmap watermark, int paddingLeft, int paddingTop) {
        return createWaterMaskBitmap(src, watermark,
                dp2px(context, paddingLeft), dp2px(context, paddingTop));
    }

    private static Bitmap createWaterMaskBitmap(Bitmap src, Bitmap watermark, int paddingLeft, int paddingTop) {
        if (src == null) {
            return null;
        }
        int width = src.getWidth();
        int height = src.getHeight();
        //创建一个bitmap
        Bitmap newb = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
        //将该图片作为画布
        Canvas canvas = new Canvas(newb);
        //在画布 0,0坐标上开始绘制原始图片
        canvas.drawBitmap(src, 0, 0, null);
        //在画布上绘制水印图片
        canvas.drawBitmap(watermark, paddingLeft, paddingTop, null);
        // 保存
        canvas.save();
        // 存储
        canvas.restore();
        return newb;
    }

    /**
     * 设置水印图片在右下角
     *
     * @param context       上下文
     * @param src
     * @param watermark
     * @param paddingRight
     * @param paddingBottom
     * @return
     */
    public static Bitmap createWaterMaskRightBottom(Context context, Bitmap src, Bitmap watermark, int paddingRight, int paddingBottom) {
        return createWaterMaskBitmap(src, watermark,
                src.getWidth() - watermark.getWidth() - dp2px(context, paddingRight),
                src.getHeight() - watermark.getHeight() - dp2px(context, paddingBottom));
    }

    /**
     * 设置水印图片到右上角
     *
     * @param context
     * @param src
     * @param watermark
     * @param paddingRight
     * @param paddingTop
     * @return
     */
    public static Bitmap createWaterMaskRightTop(Context context, Bitmap src, Bitmap watermark, int paddingRight, int paddingTop) {
        return createWaterMaskBitmap(src, watermark,
                src.getWidth() - watermark.getWidth() - dp2px(context, paddingRight),
                dp2px(context, paddingTop));
    }

    /**
     * 设置水印图片到左下角
     *
     * @param context
     * @param src
     * @param watermark
     * @param paddingLeft
     * @param paddingBottom
     * @return
     */
    public static Bitmap createWaterMaskLeftBottom(Context context, Bitmap src, Bitmap watermark, int paddingLeft, int paddingBottom) {
        return createWaterMaskBitmap(src, watermark, dp2px(context, paddingLeft),
                src.getHeight() - watermark.getHeight() - dp2px(context, paddingBottom));
    }

    /**
     * 设置水印图片到中间
     *
     * @param src
     * @param watermark
     * @return
     */
    public static Bitmap createWaterMaskCenter(Bitmap src, Bitmap watermark) {
        return createWaterMaskBitmap(src, watermark,
                (src.getWidth() - watermark.getWidth()) / 2,
                (src.getHeight() - watermark.getHeight()) / 2);
    }

    /**
     * 给图片添加文字到左上角
     *
     * @param context
     * @param bitmap
     * @param text
     * @return
     */
    public static Bitmap drawTextToLeftTop(Context context, Bitmap bitmap, String text, int size, int color, int paddingLeft, int paddingTop) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(color);
        paint.setTextSize(dp2px(context, size));
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        return drawTextToBitmap(bitmap, text, paint, bounds,
                dp2px(context, paddingLeft),
                dp2px(context, paddingTop) + bounds.height());
    }

    /**
     * 绘制文字到右下角
     *
     * @param context
     * @param bitmap
     * @param text
     * @param size
     * @param color
     * @return
     */
    public static Bitmap drawTextToRightBottom(Context context, Bitmap bitmap, String text, int size, int color, int paddingRight, int paddingBottom) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(color);
        paint.setTextSize(dp2px(context, size));
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        return drawTextToBitmap(bitmap, text, paint, bounds,
                bitmap.getWidth() - bounds.width() - dp2px(context, paddingRight),
                bitmap.getHeight() - dp2px(context, paddingBottom));
    }

    /**
     * 绘制文字到右上方
     *
     * @param context
     * @param bitmap
     * @param text
     * @param size
     * @param color
     * @param paddingRight
     * @param paddingTop
     * @return
     */
    public static Bitmap drawTextToRightTop(Context context, Bitmap bitmap, String text, int size, int color, int paddingRight, int paddingTop) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(color);
        paint.setTextSize(dp2px(context, size));
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        return drawTextToBitmap(bitmap, text, paint, bounds,
                bitmap.getWidth() - bounds.width() - dp2px(context, paddingRight),
                dp2px(context, paddingTop) + bounds.height());
    }

    /**
     * 绘制文字到左下方
     *
     * @param context
     * @param bitmap
     * @param text
     * @param size
     * @param color
     * @param paddingLeft
     * @param paddingBottom
     * @return
     */
    public static Bitmap drawTextToLeftBottom(Context context, Bitmap bitmap, String text, int size, int color, int paddingLeft, int paddingBottom) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(color);
        paint.setTextSize(dp2px(context, size));
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        return drawTextToBitmap(bitmap, text, paint, bounds,
                dp2px(context, paddingLeft),
                bitmap.getHeight() - dp2px(context, paddingBottom));
    }

    /**
     * 绘制文字到中间
     *
     * @param context
     * @param bitmap
     * @param text
     * @param size
     * @param color
     * @return
     */
    public static Bitmap drawTextToCenter(Context context, Bitmap bitmap, String text, int size, int color) {
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(color);
        paint.setTextSize(dp2px(context, size));
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        return drawTextToBitmap(bitmap, text, paint, bounds,
                (bitmap.getWidth() - bounds.width()) / 2,
                (bitmap.getHeight() + bounds.height()) / 2);
    }

    //图片上绘制文字
    private static Bitmap drawTextToBitmap(Bitmap bitmap, String text, Paint paint, Rect bounds, int paddingLeft, int paddingTop) {
        android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();

        paint.setDither(true); // 获取跟清晰的图像采样
        paint.setFilterBitmap(true);// 过滤一些
        if (bitmapConfig == null) {
            bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
        }
        bitmap = bitmap.copy(bitmapConfig, true);
        Canvas canvas = new Canvas(bitmap);

        canvas.drawText(text, paddingLeft, paddingTop, paint);
        return bitmap;
    }

    /**
     * 缩放图片
     *
     * @param src
     * @param w
     * @param h
     * @return
     */
    public static Bitmap scaleWithWH(Bitmap src, double w, double h) {
        if (w == 0 || h == 0 || src == null) {
            return src;
        } else {
            // 记录src的宽高
            int width = src.getWidth();
            int height = src.getHeight();
            // 创建一个matrix容器
            Matrix matrix = new Matrix();
            // 计算缩放比例
            float scaleWidth = (float) (w / width);
            float scaleHeight = (float) (h / height);
            // 开始缩放
            matrix.postScale(scaleWidth, scaleHeight);
            // 创建缩放后的图片
            return Bitmap.createBitmap(src, 0, 0, width, height, matrix, true);
        }
    }

    /**
     * dip转pix
     *
     * @param context
     * @param dp
     * @return
     */
    public static int dp2px(Context context, float dp) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    public static Bitmap getDefaultBitmap(String nickname ,int size,Context context ){
        Bitmap base = BitmapFactory.decodeResource(context.getResources(),R.drawable.avatar_default);
        String text;
        if (nickname!=null && nickname.length() > 0){
            if (nickname.length() >1){
                // 如果昵称有一个字以上,取最后两位
                text = nickname.substring(nickname.length()-2);
            }else {
                // 一个字就是本身
                text = nickname;
            }
            Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint.setColor(Color.WHITE);
            paint.setTextSize(dp2px(context, size));
            Rect bounds = new Rect();
            paint.getTextBounds(text, 0, text.length(), bounds);
            return drawTextToBitmap(base,text,paint,bounds,(base.getWidth() - bounds.width()) / 2,
                    (base.getHeight() + bounds.height()) / 2);
        }else {
            return base;
        }
    }



    /**
     * 保存位图到本地
     * @param bitmap
     * @param name 图片名
     * @return 图片文件
     */
    public static File  SavaImage(Bitmap bitmap,String name){
        String path = Config.PHOTO_SAVE_DIR;
        File file=new File(path);
        FileOutputStream fileOutputStream=null;
        //文件夹不存在,则创建它
        if(!file.exists()){
            file.mkdir();
        }
        String localAvatar = path+"/"+ name +".png";
        try {
            fileOutputStream=new FileOutputStream(localAvatar);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100,fileOutputStream);
            fileOutputStream.close();
            Log.d("下载头像", "SavaImage: 保存图片,地址为" + localAvatar);
            return new File(localAvatar);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 判断文件是否为图片文件(GIF,PNG,JPG),且可用
     * @param srcFilePath
     * @return
     */
    public static boolean isImage(File srcFilePath) {
        FileInputStream imgFile = null;
        byte[] b = new byte[10];
        int l = -1;
        try {
            imgFile = new FileInputStream(srcFilePath);
            l = imgFile.read(b);
            imgFile.close();
        } catch (Exception e) {
            return false;
        }
        Bitmap bitmap = BitmapFactory.decodeFile(srcFilePath.getAbsolutePath());
        try{
            bitmap.getWidth();
        }catch(Exception e) {
            return false;
        }

        if (l == 10) {
            byte b0 = b[0];
            byte b1 = b[1];
            byte b2 = b[2];
            byte b3 = b[3];
            byte b6 = b[6];
            byte b7 = b[7];
            byte b8 = b[8];
            byte b9 = b[9];

            if (b0 == (byte) 'G' && b1 == (byte) 'I' && b2 == (byte) 'F') {
                return true;
            } else if (b1 == (byte) 'P' && b2 == (byte) 'N' && b3 == (byte) 'G') {
                return true;
            } else if (b6 == (byte) 'J' && b7 == (byte) 'F' && b8 == (byte) 'I'&& b9 == (byte) 'F') {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 检查图片是否损坏
     *
     * @param filePath
     * @return
     */
    public static boolean checkImgDamage(String filePath) {
        BitmapFactory.Options options = null;
        if (options == null) {
            options = new BitmapFactory.Options();
        }
        options.inJustDecodeBounds = true;

        BitmapFactory.decodeFile(filePath, options);
        if (options.mCancel || options.outWidth == -1
                || options.outHeight == -1) {
            return true;
        }
        return false;
    }

    /**
     * 复制文件
     *
     * @param source 输入文件
     * @param target 输出文件
     */
    public static void copy(File source, File target) {
        Log.d("glide加载", "copy: 复制图片到指定路径");
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try {
            fileInputStream = new FileInputStream(source);
            fileOutputStream = new FileOutputStream(target);
            byte[] buffer = new byte[1024];
            while (fileInputStream.read(buffer) > 0) {
                fileOutputStream.write(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                fileInputStream.close();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 异步生成默认头像上传至服务器
     */


    public static void drawDefaultAvatar(DemoApplication application, Context context, String token, String username, String fullName){
        if (fullName!=null){
            Observable.just(fullName).map(new Function<String, Bitmap>() {
                @Override
                public Bitmap apply(@NonNull String s) throws Exception {
                    try {
                        return getDefaultBitmap(fullName,200,context);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    return null;
                }
            }).subscribeOn(Schedulers.io())
                    .map(new Function<Bitmap, File>() {
                        @Override
                        public File apply(@NonNull Bitmap bitmap) throws Exception {
                            try {
                                return SavaImage(bitmap,username);
                            }catch (Exception e){
                                e.printStackTrace();
                            }

                            return null;
                        }
                    }).subscribeOn(Schedulers.io())
                    .subscribe(new Observer<File>() {
                        @Override
                        public void onSubscribe(@NonNull Disposable d) {

                        }

                        @Override
                        public void onNext(@NonNull File file) {
                            String url = Config.getUrl("/system/user/profile/avatar");
                            OkHttpUtils.getInstance(context).uploadAvatar(url,file, token, new OkHttpUtils.MyCallback() {
                                @Override
                                public void success(Response response) throws IOException {
                                    JSONObject object = JSON.parseObject(response.body().string());
                                    int code = object.getInteger("code");
                                    if(code == 200){
                                        String imgUrl = object.getString("imgUrl");
                                        Log.d("默认头像", "success: 默认头像上传成功");
                                        application.setAvatar(Config.getUrl(imgUrl));
                                    }
                                }
                                @Override
                                public void failed(IOException e) {
                                    e.printStackTrace();
                                }
                            });
                        }

                        @Override
                        public void onError(@NonNull Throwable e) {

                        }

                        @Override
                        public void onComplete() {
                            Log.d("默认头像", "onComplete: 生成默认头像成功");
                        }
                    });
        }
    }



    /**?
     * 异步补充下载本地缺失头像,execute传递两个参数,第一个为手机号username决定头像文件名,
     * 第二个为头像的服务器地址,avatar
     */
    public static class downloadAvatar extends AsyncTask<String,Integer,File>{
        @Override
        protected File doInBackground(String... strings) {
            String username = strings[0];
            String avatar = strings[1];
            Observable.just(avatar).map(new Function<String, Bitmap>() {
                @Override
                public Bitmap apply(@NonNull String s) throws Exception {
                    try {
                        URL url = new URL(avatar);
                        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                        httpURLConnection.setConnectTimeout(5000);
                        int code = httpURLConnection.getResponseCode();
                        if (code == HttpURLConnection.HTTP_OK) {
                            InputStream inputStream = httpURLConnection.getInputStream();
                            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                            return bitmap;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    return null;
                }
            }).subscribeOn(Schedulers.io())
                    .map(new Function<Bitmap, File>() {
                        @Override
                        public File apply(@NonNull Bitmap bitmap) throws Exception {
                            String path = Config.PHOTO_SAVE_DIR;
                            File file = new File(path);
                            FileOutputStream fileOutputStream = null;
                            //文件夹不存在,则创建它
                            if (!file.exists()) {
                                file.mkdir();
                            }
                            String localAvatar = path + "/" + username + ".png";
                            File oldFile = new File(localAvatar);
                            if (oldFile.isFile() && oldFile.exists()) {
                                oldFile.delete();
                            }
                            try {
                                fileOutputStream = new FileOutputStream(localAvatar);
                                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
                                fileOutputStream.close();
                                Log.d("下载头像", "SavaImage: 保存图片,地址为" + localAvatar);
                                return new File(localAvatar);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            return null;
                        }
                    }).subscribeOn(Schedulers.io())
                    .subscribe(new Observer<File>() {
                        @Override
                        public void onSubscribe(@NonNull Disposable d) {

                        }

                        @Override
                        public void onNext(@NonNull File file) {
                            System.out.println("头像下载路径"+file.getAbsolutePath()+"----头像大小"+file.length());
                        }

                        @Override
                        public void onError(@NonNull Throwable e) {

                        }

                        @Override
                        public void onComplete() {

                        }
                    });
            return null;
        }
    }

    public static InputStream getInputStream(FileInputStream fileInput) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024*4];
        int n = -1;
        InputStream inputStream = null;
        try {
            while ((n=fileInput.read(buffer)) != -1) {
                baos.write(buffer, 0, n);

            }
            byte[] byteArray = baos.toByteArray();
            inputStream = new ByteArrayInputStream(byteArray);
            return inputStream;


        } catch (FileNotFoundException e) {

            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {

                    e.printStackTrace();
                }
            }
        }
    }

    public static byte[] getBitmapByte(String filepath){
        Bitmap bitmap = BitmapFactory.decodeFile(filepath);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    }

    public static void loadAvatar(Context context, String id, ImageView view) {
        File localAvatar = new File(Config.getAvatarPath((id)));
        if (localAvatar.exists() && isImage(localAvatar)) {
            Log.d("聊天界面头像", "onResume: 如果本地有图片加载本地");
            Glide.with(context)
                    .load(localAvatar)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .skipMemoryCache(true)
                    .centerCrop()
                    .placeholder(R.mipmap.default_header)
                    .into(view);
        } else {
            Log.d("聊天界面头像", "onResume: 如果本地没有图片加载服务器");
            Glide.with(context)
                    .load(view)
                    .centerCrop()
                    .thumbnail(0.1f)
                    .placeholder(R.mipmap.default_header)
                    .error(R.mipmap.default_header) // will be displayed if the image cannot be loaded
                    .into(view);
        }
    }


    /**
     * 加载头像
     * @param context 上下文
     * @param id 目标id
     * @param url 目标网络头像地址
     * @param view 目标ImageView
     */
    public static void loadAvatar(Context context, String id, String url,ImageView view) {
        File localAvatar = new File(Config.getAvatarPath((id)));
        if (localAvatar.exists() && isImage(localAvatar)) {
            Log.d("聊天界面头像", "onResume: 如果本地有图片加载本地");
            Glide.with(context)
                    .load(localAvatar)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .skipMemoryCache(true)
                    .centerCrop()
                    .into(view);
        } else {
            Log.d("聊天界面头像", "onResume: 如果本地没有图片加载服务器");
            Glide.with(context)
                    .load(url)
                    .centerCrop()
                    .thumbnail(0.1f)
                    .error(R.mipmap.default_header) // will be displayed if the image cannot be loaded
                    .into(view);
            if(url!=null){
                downloadAvatar task = new downloadAvatar();
                task.execute(id, url);
            }
        }
    }

    public static Bitmap getAvatar(Context context, String id, String url) throws ExecutionException, InterruptedException {
        File localAvatar = new File(Config.getAvatarPath((id)));
        Bitmap bitmap;
        if (localAvatar.exists() && isImage(localAvatar)) {
            Log.d("聊天界面头像", "onResume: 如果本地有图片加载本地");
            bitmap = Glide.with(context)
                    .asBitmap()
                    .load(localAvatar)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .skipMemoryCache(true)
                    .centerCrop()
                    .into(100,100)
                    .get();
        } else {
            Log.d("聊天界面头像", "onResume: 如果本地没有图片加载服务器");
            bitmap = Glide.with(context)
                    .asBitmap()
                    .load(url)
                    .centerCrop()
                    .thumbnail(0.1f)
                    .error(R.mipmap.default_header) // will be displayed if the image cannot be loaded
                    .into(100,100)
                    .get();
            if(url!=null){
                downloadAvatar task = new downloadAvatar();
                task.execute(id, url);
            }
        }
        return bitmap;
    }

    public static Bitmap getVideoImg(Context context, Bitmap baseBitmap) {
        Bitmap startBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.start_new);
        Bitmap bitmap = null;

        bitmap = Bitmap.createBitmap(baseBitmap);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        int w1 = baseBitmap.getWidth();
        int h1 = baseBitmap.getHeight();

        int w2 = startBitmap.getWidth();
        int h2 = startBitmap.getHeight();

        paint.setColor(Color.GRAY);
        paint.setAlpha(125);

        canvas.drawRect(0,0, w1, h1, paint);

        paint = new Paint();

        canvas.drawBitmap(startBitmap, Math.abs((w1 - w2)/2), Math.abs((h1 - h2)/2), paint);
        canvas.save();
        canvas.restore();

        return  bitmap;
    }

    public static Bitmap getVideoFrame(String path){
        FFmpegMediaMetadataRetriever retriever = new  FFmpegMediaMetadataRetriever();
        try {
//                        retriever.setDataSource("/storage/emulated/0/test.mp4"); //file's path
            retriever.setDataSource(path); //file's path
            Bitmap bitmap = retriever.getFrameAtTime(100000,FFmpegMediaMetadataRetriever.OPTION_CLOSEST_SYNC );  //这个时间就是第一秒的
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            retriever.release();
        }
        return null;
    }

    public static Bitmap adjustPhotoRotation(Bitmap bm, final int orientationDegree) {
        Matrix m = new Matrix();
        m.setRotate(orientationDegree, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
        try {
            Bitmap bm1 = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true);
            return bm1;
        } catch (OutOfMemoryError ex) {
        }
        return null;
    }

    /**
     * 通过设置全屏,设置状态栏透明
     *
     * @param activity
     */
    public static void fullScreen(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                //5.x开始需要把颜色设置透明,否则导航栏会呈现系统默认的浅灰色
                Window window = activity.getWindow();
                View decorView = window.getDecorView();
                //两个 flag 要结合使用,表示让应用的主体内容占用系统状态栏的空间
                int option = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
                decorView.setSystemUiVisibility(option);
                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
                window.setStatusBarColor(Color.TRANSPARENT);
                //导航栏颜色也可以正常设置
//                window.setNavigationBarColor(Color.TRANSPARENT);
            } else {
                Window window = activity.getWindow();
                WindowManager.LayoutParams attributes = window.getAttributes();
                int flagTranslucentStatus = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
                int flagTranslucentNavigation = WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
                attributes.flags |= flagTranslucentStatus;
//                attributes.flags |= flagTranslucentNavigation;
                window.setAttributes(attributes);
            }
        }
    }

    /**
     * 将View转换成Bitmap
     * @param addViewContent
     * @return
     */

    public static Bitmap getViewBitmap(View addViewContent) {

        addViewContent.setDrawingCacheEnabled(true);

        addViewContent.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        addViewContent.layout(0, 0,
                addViewContent.getMeasuredWidth(),
                addViewContent.getMeasuredHeight());

        addViewContent.buildDrawingCache();
        Bitmap cacheBitmap = addViewContent.getDrawingCache();
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

        return bitmap;
    }
}

图片压缩鲁班压缩

                Luban.with(ClipAvatar.this)
                        .load(file)                                   // 传人要压缩的图片列表
                        .ignoreBy(100)                                  // 忽略不压缩图片的大小
                        .setTargetDir(Config.PHOTO_SAVE_DIR)                        // 设置压缩后文件存储位置
                        .setCompressListener(new OnCompressListener() { //设置回调
                            @Override
                            public void onStart() {

                                Log.d(TAG, "onStart: 压缩前图片大小:"+file.length());
                            }

                            @Override
                            public void onSuccess(File file) {

                                File compressAvatar = file;
                                Log.d(TAG, "onSuccess: 压缩成功后图片大小"+compressAvatar.length());
                                String url = Config.getUrl("/system/user/profile/avatar");
                                OkHttpUtils.getInstance(ClipAvatar.this).uploadAvatar(url,compressAvatar,
                                        application.getToken(), new OkHttpUtils.MyCallback() {
                                            @Override
                                            public void success(Response response) throws IOException {
                                                JSONObject object = JSON.parseObject(response.body().string());
                                                int code = object.getInteger("code");
                                                String msg = object.getString("msg");
                                                ClipAvatar.this.runOnUiThread(() -> Toast.makeText(ClipAvatar.this,msg,Toast.LENGTH_LONG).show());
                                                if(code == 200){
                                                    String imgUrl = object.getString("imgUrl");
                                                    //服务器返回地址类型: "imgUrl": "/profile/avatar/2022/03/08/3cd6f0f2-8a77-43e2-b105-401ef0e7f123.jpg",
                                                    //路径补全
                                                    String avatar = "http://" + Config.BeiDou_SERVER_HOST + ":" + Config.BeiDou_SERVER_PORT + imgUrl;
                                                    application.setAvatar(avatar);
                                                    File savaAvatar = new File(Config.getAvatarPath(application.getUserID()));
                                                    copy(compressAvatar,savaAvatar);
                                                }
                                            }
                                            @Override
                                            public void failed(IOException e) {
                                                e.printStackTrace();
                                            }
                                        });
                            }

                            @Override
                            public void onError(Throwable e) {

                                Log.d(TAG, "onError: 压缩失败");
                            }
                        }).launch();    //启动压缩

头像裁剪

    <com.githang.clipimage.ClipImageView
        android:id="@+id/clip_image_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?attr/actionBarSize"
        app:civHeight="3"
        app:civMaskColor="#CC000000"
        app:civClipPadding="30dp"
        app:civWidth="3" />

ClipImageLayout相当于一个图片裁剪的容器,在裁剪完毕后可以使用.clip()方法,即可获取到裁剪后的Bitmap图片。

        mClipImageLayout = (ClipImageView) findViewById(R.id.clip_image_view);
        Intent intent = getIntent();
        String imagePath = intent.getStringExtra("imagePath");
        bitmap = BitmapFactory.decodeFile(imagePath);
        mClipImageLayout.setImageBitmap(bitmap);
ClippedBitmap = mClipImageLayout.clip();

拍照录制视频

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.cjt2325.cameralibrary.JCameraView
        android:id="@+id/cameraView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:iconMargin="20dp"
        app:iconSize="30dp"
        app:iconSrc="@drawable/ic_camera_enhance_black_24dp" />

</RelativeLayout>

使用相机需要权限:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <!-- 摄像头权限 -->
    <uses-permission android:name="android.permission.CAMERA" />
package com.beidouapp.ui.Setting;

import static com.beidouapp.model.utils.ImageUtil.SavaImage;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.beidouapp.Config;
import com.beidouapp.R;
import com.cjt2325.cameralibrary.JCameraView;
import com.cjt2325.cameralibrary.listener.JCameraListener;

import java.io.File;

/**
 * 拍照、拍摄,作为其他activity的onActivityResult目标
 * 返回data有两个参数,一个是type:photo/video(区分拍照和摄影),一个是path,返回本地文件名
 */

public class TakePhoto extends AppCompatActivity {
    private JCameraView mJCameraView;
    private static final String TAG = "拍照";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_take_photo);
        initView();
    }

    private void initView() {
        mJCameraView = findViewById(R.id.cameraView);
        //(0.0.7+)设置视频保存路径(如果不设置默认为Environment.getExternalStorageDirectory().getPath())
        mJCameraView.setSaveVideoPath(Environment.getExternalStorageDirectory().getPath());
        //(0.0.8+)设置手动/自动对焦,默认为自动对焦
        //设置小视频保存路径
        File file = new File(Config.VIDEO_SAVE_DIR);
        if (!file.exists()) {
            file.mkdirs();
        }
        Log.d(TAG, "initView: "+file.getAbsolutePath());
        mJCameraView.setSaveVideoPath(Config.VIDEO_SAVE_DIR);
        mJCameraView.setJCameraLisenter(new JCameraListener() {

            @Override
            public void captureSuccess(Bitmap bitmap) {
                //获取到拍照成功后返回的Bitmap
                File photoFile = SavaImage(bitmap, "takePhoto"+System.currentTimeMillis());
                Intent data = new Intent();
                data.putExtra("type", "photo");
                data.putExtra("path", photoFile.getAbsolutePath());
                Log.d(TAG, "captureSuccess: "+photoFile.getAbsolutePath());
                setResult(RESULT_OK, data);
                finish();
            }

            @Override
            public void recordSuccess(String url, Bitmap firstFrame) {
                //获取成功录像后的视频路径
                Intent data = new Intent();
                data.putExtra("type", "video");
                data.putExtra("path", url);
                setResult(RESULT_OK, data);
                finish();
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mJCameraView != null) {
            mJCameraView.onResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mJCameraView != null) {
            mJCameraView.onPause();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值