Android通過代碼生成長圖並保存本地

hello大家好,我是斯普潤,很久沒有更新博客了。因爲最近一直在趕項目,不停加班。難得有時間閒下來寫寫博客。最近也在抽時間學習flutter,作爲一枚程序猿當然不能停止學習的腳步啦~

說遠了,今天分享下用代碼生成長圖並保存到本地的功能。當點擊分享按鈕後,會在後臺生成長圖的Bitmap,點擊保存會將Bitmap存到本地jpg文件。先來看看我實現的效果。

   

其實原理很簡單,首先生成一個空白的畫布,然後通過本地的xml佈局文件獲取layout,將layout轉成Bitmap,通過Canvas繪製出來,唯一需要注意的就是計算高度。我這裏將其拆分成了三塊,頭佈局只有文字和頭像,中佈局全部是圖片,尾佈局高度指定,由於圖片需要根據寬度去收縮放大,所以計算中佈局稍微麻煩一點,將需要繪製的圖片下載到本地,所以使用前需要先申請存儲權限!將圖片收縮或放大至指定寬度,計算出此時的圖片高度,將所有圖片高度與間距高度累加,就得到了中佈局的總高度。

說了這麼多,先來看我的代碼吧~ 註釋都有,就不過多解釋了,有些工具類,你們替換一下就可以了,比如SharePreUtil、DimensionUtil、QRCodeUtil等等,不需要可以去掉

import android.Manifest;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloader;
import com.tbruyelle.rxpermissions2.RxPermissions;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class LongPoster extends LinearLayout {

    private String TAG = this.getClass().getName();

    private Context context;
    private View rootView;
    private Listener listener;

    private LinearLayout topViewLl, contentLl;
    private FrameLayout bottomViewFl;
    private TextView appNameTv, nameTv, courseNameTv, courseDetailTv, codeContentTv;


    // 長圖的寬度,默認爲屏幕寬度
    private int longPictureWidth;
    // 長圖兩邊的間距
    private int leftRightMargin;
    // 圖片的url集合
    private List<String> imageUrlList;
    // 保存下載後的圖片url和路徑鍵值對的鏈表
    private LinkedHashMap<String, String> localImagePathMap;
    //每張圖的高度
    private Map<Integer, Integer> imgHeightMap;

    private int topHeight = 0;
    private int contentHeight = 0;
    private int bottomHeight = 0;
    //是否包含頭像
    private boolean isContainAvatar = false;
    private Bitmap qrcodeBit;
    private List<Bitmap> tempList;

    public static void createPoster(InitialActivity activity, LongPosterBean bean, Listener listener) {
        new RxPermissions(activity).request(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(granted -> {
                    if (granted) {
                        activity.showInfoProgressDialog(activity, "海報生成中...");
                        LongPoster poster = new LongPoster(activity);
                        poster.setListener(listener);
                        poster.setCurData(bean);
                    } else {
                        ToastUtil.showShort(activity, "請獲取存儲權限");
                        listener.onFail();
                    }
                });
    }


    public LongPoster(Context context) {
        super(context);
        init(context);
    }

    public LongPoster(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public LongPoster(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public void removeListener() {
        this.listener = null;
    }

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    private void init(Context context) {
        this.context = context;

        tempList = new ArrayList<>();
        //這裏去獲取屏幕高度,我這裏默認1080
        longPictureWidth = 1080;
        leftRightMargin = DimensionUtil.dp2pxInt(15);
        rootView = LayoutInflater.from(context).inflate(R.layout.layout_draw_canvas, this, false);
        initView();
    }

    private void initView() {
        topViewLl = rootView.findViewById(R.id.ll_top_view);
        contentLl = rootView.findViewById(R.id.ll_content);
        bottomViewFl = rootView.findViewById(R.id.fl_bottom_view);

        appNameTv = rootView.findViewById(R.id.app_name_tv);
        nameTv = rootView.findViewById(R.id.tv_name);
        courseNameTv = rootView.findViewById(R.id.tv_course_name);
        courseDetailTv = rootView.findViewById(R.id.tv_course_detail_name);
        codeContentTv = rootView.findViewById(R.id.qr_code_content_tv);

        imageUrlList = new ArrayList<>();
        localImagePathMap = new LinkedHashMap<>();
        imgHeightMap = new HashMap<>();
    }

    public void setCurData(LongPosterBean bean) {
        imageUrlList.clear();
        localImagePathMap.clear();

        String icon = SharedPreUtil.getString("userIcon", "");
        if (!TextUtils.isEmpty(icon)) {
            imageUrlList.add(StringUtil.handleImageUrl(icon));
            isContainAvatar = true;
        }

        if (bean.getPhotoList() != null) {
            for (String str : bean.getPhotoList()) {
                imageUrlList.add(StringUtil.handleImageUrl(str));
            }
        }

        appNameTv.setText(R.string.app_name);
        nameTv.setText(SharedPreUtil.getString("userNickName", ""));
        String courseNameStr = "我在" + getResources().getString(R.string.app_name) + "學" + bean.getCourseName();
        SpannableString ss = new SpannableString(courseNameStr);

        ss.setSpan(new ForegroundColorSpan(Color.parseColor("#333333")),
                courseNameStr.length() - bean.getCourseName().length(), courseNameStr.length(),
                SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);

        courseNameTv.setText(ss);
        courseDetailTv.setText(bean.getDetailName());
        codeContentTv.setText("掃描二維碼\n查看" + bean.getCourseName());

        if (!TextUtils.isEmpty(bean.getQrCodeUrl())) {
            int width = (int) DimensionUtil.dp2px(120);
            qrcodeBit = QRCodeUtil.createQRCodeBitmap(bean.getQrCodeUrl(), width, width);
            tempList.add(qrcodeBit);
        }
        downloadAllPic();
    }

    private void downloadAllPic() {
        //下載方法,這裏替換你選用的三方庫,或者你可以選用我使用的這個三方庫
        //implementation 'com.liulishuo.filedownloader:library:1.7.4'
        if (imageUrlList.isEmpty()) return;

        FileDownloader.setup(context);
        FileDownloadListener queueTarget = new FileDownloadListener() {
            @Override
            protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void blockComplete(BaseDownloadTask task) {
            }

            @Override
            protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
            }

            @Override
            protected void completed(BaseDownloadTask task) {
                localImagePathMap.put(task.getUrl(), task.getTargetFilePath());
                if (localImagePathMap.size() == imageUrlList.size()) {
                    //全部圖片下載完成開始繪製
                    measureHeight();
                    drawPoster();
                }
            }

            @Override
            protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void error(BaseDownloadTask task, Throwable e) {
                listener.onFail();
                e.printStackTrace();
            }

            @Override
            protected void warn(BaseDownloadTask task) {
            }
        };

        for (String url : imageUrlList) {
            String storePath = BitmapUtil.getImgFilePath();
            FileDownloader.getImpl().create(url)
                    .setCallbackProgressTimes(0)
                    .setListener(queueTarget)
                    .setPath(storePath)
                    .asInQueueTask()
                    .enqueue();
        }

        FileDownloader.getImpl().start(queueTarget, true);
    }

    private void measureHeight() {
        layoutView(topViewLl);
        layoutView(contentLl);
        layoutView(bottomViewFl);

        topHeight = topViewLl.getMeasuredHeight();
        //原始高度加上圖片總高度
        contentHeight = contentLl.getMeasuredHeight() + getAllImageHeight();
        bottomHeight = bottomViewFl.getMeasuredHeight();
//        LogUtil.d(TAG, "drawLongPicture layout top view = " + topHeight + " × " + longPictureWidth);
//        LogUtil.d(TAG, "drawLongPicture layout llContent view = " + contentHeight);
//        LogUtil.d(TAG, "drawLongPicture layout bottom view = " + bottomHeight);
    }

    /**
     * 繪製方法
     */
    private void drawPoster() {
        // 計算出最終生成的長圖的高度 = 上、中、圖片總高度、下等個個部分加起來
        int allBitmapHeight = topHeight + contentHeight + bottomHeight;

        // 創建空白畫布
        Bitmap.Config config = Bitmap.Config.RGB_565;
        Bitmap bitmapAll = Bitmap.createBitmap(longPictureWidth, allBitmapHeight, config);

        Canvas canvas = new Canvas(bitmapAll);
        canvas.drawColor(Color.WHITE);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setFilterBitmap(true);

        // 繪製top view
        Bitmap topBit = BitmapUtil.getLayoutBitmap(topViewLl, longPictureWidth, topHeight);
        canvas.drawBitmap(topBit, 0, 0, paint);

        //繪製頭像
        Bitmap avatarBit;
        if (isContainAvatar) {
            int aWidth = (int) DimensionUtil.dp2px(77);
            avatarBit = BitmapUtil.resizeImage(BitmapFactory.decodeFile(localImagePathMap.get(imageUrlList.get(0))), aWidth, aWidth);
        } else {
            avatarBit = BitmapUtil.drawableToBitmap(context.getDrawable(R.drawable.placeholder));
        }
        if (avatarBit != null) {
            avatarBit = BitmapUtil.getOvalBitmap(avatarBit, (int) DimensionUtil.dp2px(38));
            canvas.drawBitmap(avatarBit, DimensionUtil.dp2px(20), DimensionUtil.dp2px(70), paint);
        }

        //繪製中間圖片列表
        if (isContainAvatar && imageUrlList.size() > 1) {
            Bitmap bitmapTemp;
            int top = (int) (topHeight + DimensionUtil.dp2px(20));
            for (int i = 1; i < imageUrlList.size(); i++) {
                String filePath = localImagePathMap.get(imageUrlList.get(i));
                bitmapTemp = BitmapUtil.fitBitmap(BitmapFactory.decodeFile(filePath),
                        longPictureWidth - leftRightMargin * 2);
                if (i > 1)
                    top += imgHeightMap.get(i - 1) + DimensionUtil.dp2px(10);
                canvas.drawBitmap(bitmapTemp, leftRightMargin, top, paint);
                tempList.add(bitmapTemp);
            }
        } else if (!isContainAvatar && !imageUrlList.isEmpty()) {
            Bitmap bitmapTemp;
            int top = (int) (topHeight + DimensionUtil.dp2px(20));
            for (int i = 0; i < imageUrlList.size(); i++) {
                String filePath = localImagePathMap.get(imageUrlList.get(i));
                bitmapTemp = BitmapUtil.fitBitmap(BitmapFactory.decodeFile(filePath),
                        longPictureWidth - leftRightMargin * 2);
                if (i > 0)
                    top += imgHeightMap.get(i - 1) + DimensionUtil.dp2px(10);
                canvas.drawBitmap(bitmapTemp, leftRightMargin, top, paint);
                tempList.add(bitmapTemp);
            }
        }

        // 繪製bottom view
        Bitmap bottomBit = BitmapUtil.getLayoutBitmap(bottomViewFl, longPictureWidth, bottomHeight);
        canvas.drawBitmap(bottomBit, 0, topHeight + contentHeight, paint);

        // 繪製QrCode
        //if (qrcodeBit != null)
            //canvas.drawBitmap(qrcodeBit, longPictureWidth - DimensionUtil.dp2px(150),
                    //topHeight + contentHeight + DimensionUtil.dp2px(15), paint);

        //保存最終的圖片
        String time = String.valueOf(System.currentTimeMillis());
        boolean state = BitmapUtil.saveImage(bitmapAll, context.getExternalCacheDir() +
                    File.separator, time, Bitmap.CompressFormat.JPEG, 80);

        //繪製回調
        if (listener != null) {
            if (state) {
                listener.onSuccess(context.getExternalCacheDir() + File.separator + time);
            } else {
                listener.onFail();
            }
        }

        //清空所有Bitmap
        tempList.add(topBit);
        tempList.add(avatarBit);
        tempList.add(bottomBit);
        tempList.add(bitmapAll);
        for (Bitmap bit : tempList) {
            if (bit != null && !bit.isRecycled()) {
                bit.recycle();
            }
        }
        tempList.clear();

        //繪製完成,刪除所有保存的圖片
        for (int i = 0; i < imageUrlList.size(); i++) {
            String path = localImagePathMap.get(imageUrlList.get(i));
            File file = new File(path);
            if (file.exists()) {
                file.delete();
            }
        }
    }

    /**
     * 獲取當前下載所有圖片的高度,忽略頭像
     */
    private int getAllImageHeight() {
        imgHeightMap.clear();
        int height = 0;
        int startIndex = 0;
        int cutNum = 1;
        if (isContainAvatar) {
            cutNum = 2;
            startIndex = 1;
        }

        for (int i = startIndex; i < imageUrlList.size(); i++) {
            Bitmap tamp = BitmapUtil.fitBitmap(BitmapFactory.decodeFile(localImagePathMap.get(imageUrlList.get(i))),
                    longPictureWidth - leftRightMargin * 2);
            height += tamp.getHeight();
            imgHeightMap.put(i, tamp.getHeight());
            tempList.add(tamp);
        }

        height = (int) (height + DimensionUtil.dp2px(10) * (imageUrlList.size() - cutNum));
        return height;
    }


    /**
     * 手動測量view寬高
     */
    private void layoutView(View v) {
        v.layout(0, 0, DoukouApplication.screenWidth, DoukouApplication.screenHeight);
        int measuredWidth = View.MeasureSpec.makeMeasureSpec(DoukouApplication.screenWidth, View.MeasureSpec.EXACTLY);
        int measuredHeight = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        v.measure(measuredWidth, measuredHeight);
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
    }

    public interface Listener {

        /**
         * 生成長圖成功的回調
         *
         * @param path 長圖路徑
         */
        void onSuccess(String path);

        /**
         * 生成長圖失敗的回調
         */
        void onFail();
    }
}

接下來是界面佈局,由於圖片先下載再繪製的,所以不需要圖片控件,只需要預留出圖片的位置就可以了~

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/ll_top_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="15dp"
            android:paddingRight="15dp">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="25dp"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/app_name_tv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#fffb4e90"
                    android:textSize="18sp" />

                <View
                    android:layout_width="1dp"
                    android:layout_height="14dp"
                    android:layout_marginHorizontal="10dp"
                    android:background="@color/colorPrimary" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="#fffb4e90"
                    android:textSize="18sp" />

            </LinearLayout>

            <FrameLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp">

                <TextView
                    android:id="@+id/tv_name"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="87dp"
                    android:layout_marginTop="8dp"
                    android:textColor="@color/c33"
                    android:textSize="18sp" />

                <TextView
                    android:id="@+id/tv_course_name"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="87dp"
                    android:layout_marginTop="43dp"
                    android:textColor="@color/c66"
                    android:textSize="18sp" />

            </FrameLayout>

            <TextView
                android:id="@+id/tv_course_detail_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="28dp"
                android:background="@drawable/shape_black_radius2"
                android:paddingHorizontal="22dp"
                android:paddingVertical="10dp"
                android:textColor="#ffffffff"
                android:textSize="15sp" />

        </LinearLayout>

        <LinearLayout
            android:id="@+id/ll_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:paddingLeft="15dp"
            android:paddingTop="20dp"
            android:paddingRight="15dp"
            android:paddingBottom="10dp" />

        <FrameLayout
            android:id="@+id/fl_bottom_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:orientation="horizontal"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            android:paddingBottom="20dp">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:scaleType="fitXY"
                android:src="@drawable/bg_qr_code" />

            <TextView
                android:id="@+id/qr_code_content_tv"
                android:layout_width="175dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="15dp"
                android:ellipsize="end"
                android:maxLines="3"
                android:textColor="@color/white"
                android:textSize="15sp" />

        </FrameLayout>

    </LinearLayout>

</ScrollView>

BitmapUtil工具類~

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;

import com.tbruyelle.rxpermissions2.RxPermissions;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.UUID;


public class BitmapUtil {

    private static final String TAG = "BitmapUtil";

 
    /**
     * 將Bitmap轉成圖片保存本地
     */
    public static boolean saveImage(Bitmap bitmap, String filePath, String filename, Bitmap.CompressFormat format, int quality) {
        if (quality > 100) {
            Log.d("saveImage", "quality cannot be greater that 100");
            return false;
        }
        File file;
        FileOutputStream out = null;
        try {
            switch (format) {
                case PNG:
                    file = new File(filePath, filename);
                    out = new FileOutputStream(file);
                    return bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
                case JPEG:
                    file = new File(filePath, filename);
                    out = new FileOutputStream(file);
                    return bitmap.compress(Bitmap.CompressFormat.JPEG, quality, out);
                default:
                    file = new File(filePath, filename + ".png");
                    out = new FileOutputStream(file);
                    return bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * drawable 轉 bitmap
     */
    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;
    }

    public static void saveImage(FragmentActivity context, Bitmap bmp, boolean recycle) {
        new RxPermissions(context).request(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(granted -> {
                    if (granted) {
                        if (BitmapUtil.saveImageToGallery(context, bmp)) {
                            ToastUtil.showShort(context, "保存成功");
                        } else {
                            ToastUtil.showShort(context, "保存失敗");
                        }
                    } else {
                        ToastUtil.showShort(context, "請獲取存儲權限");
                    }
                    if (recycle) bmp.recycle();
                });
    }

    //保存圖片到指定路徑
    private static boolean saveImageToGallery(FragmentActivity context, Bitmap bmp) {
        // 首先保存圖片
        String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +
                Environment.DIRECTORY_PICTURES + File.separator + "test";
        File appDir = new File(storePath);
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(appDir, fileName);
        try {
            FileOutputStream fos = new FileOutputStream(file);
            //通過io流的方式來壓縮保存圖片
            boolean isSuccess = bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
            fos.flush();
            fos.close();

            //把文件插入到系統圖庫
//            MediaStore.Images.Media.insertImage(context.getContentResolver(), bmp, fileName, null);

            //保存圖片後發送廣播通知更新數據庫
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri uri = Uri.fromFile(new File(file.getAbsolutePath()));
            LogUtil.e("路徑============", file.getAbsolutePath());
            intent.setData(uri);
            context.sendBroadcast(intent);

            return isSuccess;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    public static String getImgFilePath() {
        String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +
                Environment.DIRECTORY_PICTURES + File.separator + "test" + File.separator;
        File appDir = new File(storePath);
        if (!appDir.exists()) {
            appDir.mkdir();
        }
        return storePath + UUID.randomUUID().toString().replace("-", "") + ".jpg";
    }


    /***
     * 得到指定半徑的圓形Bitmap
     * @param bitmap 圖片
     * @param radius 半徑
     * @return bitmap
     */
    public static Bitmap getOvalBitmap(Bitmap bitmap, int radius) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        float scaleWidth = ((float) 2 * radius) / width;

        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleWidth);

        bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

        final RectF rectF = new RectF(rect);

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);

        canvas.drawOval(rectF, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    /**
     * layout佈局轉Bitmap
     *
     * @param layout 佈局
     * @param w      寬
     * @param h      高
     * @return bitmap
     */
    public static Bitmap getLayoutBitmap(ViewGroup layout, int w, int h) {
        Bitmap originBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(originBitmap);
        layout.draw(canvas);
        return resizeImage(originBitmap, w, h);
    }

    public static Bitmap resizeImage(Bitmap origin, int newWidth, int newHeight) {
        if (origin == null) {
            return null;
        }
        int height = origin.getHeight();
        int width = origin.getWidth();
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap newBM = Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
        if (!origin.isRecycled()) {
            origin.recycle();
        }
        return newBM;
    }


    /**
     * fuction: 設置固定的寬度,高度隨之變化,使圖片不會變形
     *
     * @param target   需要轉化bitmap參數
     * @param newWidth 設置新的寬度
     * @return
     */
    public static Bitmap fitBitmap(Bitmap target, int newWidth) {
        int width = target.getWidth();
        int height = target.getHeight();
        Matrix matrix = new Matrix();
        float scaleWidth = ((float) newWidth) / width;
        // float scaleHeight = ((float)newHeight) / height;
        int newHeight = (int) (scaleWidth * height);
        matrix.postScale(scaleWidth, scaleWidth);
        // Bitmap result = Bitmap.createBitmap(target,0,0,width,height,
        // matrix,true);
        Bitmap bmp = Bitmap.createBitmap(target, 0, 0, width, height, matrix,
                true);
        if (target != null && !target.equals(bmp) && !target.isRecycled()) {
            target.recycle();
            target = null;
        }
        return bmp;// Bitmap.createBitmap(target, 0, 0, width, height, matrix,
        // true);
    }
}

嗯,好了,大致代碼就是以上這些,不過有些方法需要替換成你們自己的哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章