用Rxjava完成画图

效果:

描述:后边的背景是固定的,但是二维码和用户有关,所以要后生成 并且和后边背景合并为一个bitmap  用于分享

原来我是用最常用的方法来通过异步来合成图片的

代码如下

protected Integer[] imgUrls = {R.drawable.share_bg1,
        R.drawable.share_bg2,
        R.drawable.share_bg3,
        R.drawable.share_bg4,
        R.drawable.share_bg5}; 
  protected Runnable drawingSharePic = new Runnable() {
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        @Override
        public void run() {
            try {
                isDrawing = true;
                for (int i = 0; i < imgUrls.length; i++) {
                    LogUtil.e("");
                    Bitmap bitmapBg = BitmapFactory.decodeResource(getResources(), imgUrls[i]);//这里
                    Bitmap bitmapShare = SharePictureCreator.drawPicture(activity, getShareUrl(), bitmapBg);
                    if (mListShare == null) {
                        return;
                    }
                    mListShare.add(bitmapShare);
                    bitmapBg.recycle();
                    bitmapBg = null;
                }

                if (mListShare.size() > 1) {
                    Bitmap bitmap0 = mListShare.get(0);
                    Bitmap bitmapEnd = mListShare.get(mListShare.size() - 1);
                    mListShare.add(0, bitmapEnd);
                    mListShare.add(bitmap0);
                }
                isPicSuccess = true;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        dismissProgressDialog();

                        LogUtil.e("mListImgShare的长度====>>" + mListShare.size());
                        if (mShareAdapter == null) {
                            mShareAdapter = new ShareChoosePagerAdapter();
                            viewPager_share.setAdapter(mShareAdapter);
                            viewPager_share.setCurrentItem(2);
                            return;
                        }
                        if (mShareAdapter != null) {
                            mShareAdapter.notifyDataSetChanged();
                        }
                        viewPager_share.setCurrentItem(2);
                    }
                });
            } catch (ExecutionException e) {
                dismissProgressDialog();
                isPicSuccess = false;
                e.printStackTrace();
            } catch (InterruptedException e) {
                dismissProgressDialog();
                isPicSuccess = false;
                e.printStackTrace();
            } finally {
                isDrawing = false;
            }

        }
    };
 new Thread(drawingSharePic).start();

我昨天看了一个人分享rxjava的用法,想用rxjava试试 就改变了写法 后来运行,证明效果一样 贴出来大家分享一下

这个人的文章地址-->>http://gank.io/post/560e15be2dca930e00da1083 写的很详细

    Observable.from(imgUrls)//
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.newThread())//开启新线程 下边的map是这个子线程要完成的东西
                .map(new Func1<Integer, Bitmap>() {
                    @Override
                    public Bitmap call(Integer integer) {
                        isDrawing = true;
                        try {
                            Bitmap bitmapBg = BitmapFactory.decodeResource(getResources(), integer);
                            Bitmap bitmapShare = SharePictureCreator.drawPicture(activity, getShareUrl(), bitmapBg, mListTxt);
                            return bitmapShare;
                        } catch (ExecutionException e) {
                            e.printStackTrace();
                            return null;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            return null;
                        }finally {
                            isDrawing=false;
                        }
                    }
                }).observeOn(Schedulers.io())//开启一个io线程 在上边的子线程完成之后,
                .map(new Func1<Bitmap, List<Bitmap>>() {//这个里是io线程里需要做的事情
                    @Override
                    public List<Bitmap> call(Bitmap bitmap) {
                        isPicSuccess = true;
                        mListShare.add(bitmap);
                        return mListShare;
                    }
                }).subscribe(new Action1<List<Bitmap>>() {//这个是安卓给安卓控件加数据了 
            @Override
            public void call(List<Bitmap> bitmaps) {
                dismissProgressDialog();
                LogUtil.e("mListImgShare的长度====>>" + mListShare.size());
                if (mListShare.size() > 1) {
                    Bitmap bitmap0 = mListShare.get(0);
                    Bitmap bitmapEnd = mListShare.get(mListShare.size() - 1);
                    mListShare.add(0, bitmapEnd);
                    mListShare.add(bitmap0);
                }
                if (mShareAdapter == null) {
                    mShareAdapter = new ShareChoosePagerAdapter();
                    viewPager_share.setAdapter(mShareAdapter);
                    viewPager_share.setCurrentItem(2);
                    return;
                }
                if (mShareAdapter != null) {
                    mShareAdapter.notifyDataSetChanged();
                }
                viewPager_share.setCurrentItem(2);
            }
        });

下边是将背景和二维码合成的工具

//这个是我用来合并背景和二维码的类  需要依赖zxing
public class SharePictureCreator {
    public static String TAG = "SharePictureCreator=======>>";
    static int relativeWidth = 640;
    static int relativeHeight = 1130;
//以上的数都是ui给的像素都是按照640*1130来给的 为了保证画的位置不变 ,需要进行适配
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static Bitmap drawPicture(final Activity activity,
                                     String url_login,
                                     Bitmap bitmap_background
            ) throws ExecutionException, InterruptedException {
        Paint paint = new Paint();
        paint.setColor(Color.argb(255, 0, 0, 0));
        paint.setStrokeWidth(20);
        paint.setAntiAlias(true);
        //背景bitmap
        int widthBg = (int) (bitmap_background.getWidth());
        int heightBg = (int) (bitmap_background.getHeight());
        //要分享的bitmap
        Bitmap bitmapShare = Bitmap.createBitmap(widthBg, heightBg, bitmap_background.getConfig());
//        Bitmap  bitmapShare=BitmapUtils.getZoomImage(bitmapShareBig,widthBg/2,heightBg/2);
        Canvas canvas = new Canvas(bitmapShare);
        canvas.drawBitmap(bitmap_background, 0, 0, paint);
        //写文字  这个功能我不做了  如果要的话 我传了一个list<string>;
       // int txtLeft = 48 * widthBg / relativeWidth;
        //int txtTop = 766 * heightBg / relativeHeight;
        //int space = 25 * widthBg / relativeWidth;
        //paint.setTextSize(20 * widthBg / relativeWidth);// 字体大小 
        //paint.setStrokeWidth(30);
        //if (list_txt != null) {
            //for (int i = 0; i < list_txt.size(); i++) {
              //  canvas.drawText(list_txt.get(i), txtLeft, txtTop + i * space, paint);
          //  }
      //  } 
        //二维码生成
        try {
            int leftQCode = 456 * widthBg / relativeWidth;//二维码距离左边的距离
            int topQCode = 907 * heightBg / relativeHeight;//二维码距离top的距离
            int leftQCodeBg = 454 * widthBg / relativeWidth;//二维码后边有个绿色的框 我就画的实心的正方形  让二维码覆盖上了这个是他的left距离
            int topQCodeBG = 905 * heightBg / relativeHeight;//绿色背景的top距离
            int rightQCodeBg = (454 +160)* widthBg / relativeWidth;//绿色背景的left距离
            int bottomQCodeBG = (905+160) * heightBg / relativeHeight;//绿色背景的bottom距离
            paint.setARGB(255, 34, 139, 34);
            paint.setColor(activity.getResources().getColor(R.color.green_base));
            canvas.drawRect(leftQCodeBg, topQCodeBG, rightQCodeBg, bottomQCodeBG, paint);
//          Bitmap bitmap_code = CodeCreator.createQRCode(activity, url_login, 120 * widthBg / relativeWidth, 120 * widthBg / relativeWidth);
            //二维码中间那个logo  
            Bitmap bitmapLogo = BitmapFactory.decodeResource(activity.getResources(), R.mipmap.ic_launcher);
            Bitmap bitmap_code = LogoCofig.createCode(url_login, bitmapLogo);
            // 这个就是变化一下bitmap的大小
            Bitmap bitmapCodeUse = BitmapUtils.getZoomImage(bitmap_code, 156 * widthBg / relativeWidth, 156 * widthBg / relativeWidth);
            canvas.drawBitmap(bitmapCodeUse, leftQCode, topQCode, paint);
            Bitmap zoomImage = BitmapUtils.getZoomImage(bitmapShare, bitmapShare.getWidth() / 2, bitmapShare.getHeight() / 2);
            return zoomImage;
        } catch (WriterException e) {
            return null;
        }

    }
}

生成二维码的工具
public class LogoCofig {
    public class LogoConfig {
        /**
         * @return 返回带有白色背景框logo
         */
        public Bitmap modifyLogo(Bitmap bgBitmap, Bitmap logoBitmap) {

            int bgWidth = bgBitmap.getWidth();
            int bgHeigh = bgBitmap.getHeight();
            //通过ThumbnailUtils压缩原图片,并指定宽高为背景图的3/4
            logoBitmap = ThumbnailUtils.extractThumbnail(logoBitmap,bgWidth*3/4, bgHeigh*3/4, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
            Bitmap cvBitmap = Bitmap.createBitmap(bgWidth, bgHeigh, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(cvBitmap);
            // 开始合成图片
            canvas.drawBitmap(bgBitmap, 0, 0, null);
            canvas.drawBitmap(logoBitmap,(bgWidth - logoBitmap.getWidth()) /2,(bgHeigh - logoBitmap.getHeight()) / 2, null);
            canvas.save(Canvas.ALL_SAVE_FLAG);// 保存
            canvas.restore();
            if(cvBitmap.isRecycled()){
                cvBitmap.recycle();
            }
            return cvBitmap;
        }
    }
    /**
     * 黑点颜色
     */
    private static final int BLACK = 0xFF000000;
    /**
     * 白色
     */
    private static final int WHITE = 0xFFFFFFFF;
    /**
     * 正方形二维码宽度
     */
    private static final int CODE_WIDTH = 440;
    /**
     * LOGO宽度值,最大不能大于二维码20%宽度值,大于可能会导致二维码信息失效
     */
    private static final int LOGO_WIDTH_MAX = CODE_WIDTH / 5;
    /**
     *LOGO宽度值,最小不能小于二维码10%宽度值,小于影响Logo与二维码的整体搭配
     */
    private static final int LOGO_WIDTH_MIN = CODE_WIDTH / 10;
    /**
     * 生成带LOGO的二维码
     */

    public static Bitmap createCode(String content, Bitmap logoBitmap)
            throws WriterException {
        int logoWidth = logoBitmap.getWidth();
        int logoHeight = logoBitmap.getHeight();
        int logoHaleWidth = logoWidth >= CODE_WIDTH ? LOGO_WIDTH_MIN
                : LOGO_WIDTH_MAX;
        int logoHaleHeight = logoHeight >= CODE_WIDTH ? LOGO_WIDTH_MIN
                : LOGO_WIDTH_MAX;
        // 将logo图片按martix设置的信息缩放
        Matrix m = new Matrix();
        /*
         * 给的源码是,由于CSDN上传的资源不能改动,这里注意改一下
         * float sx = (float) 2*logoHaleWidth / logoWidth;
         * float sy = (float) 2*logoHaleHeight / logoHeight;
         */
        float sx = (float) logoHaleWidth / logoWidth;
        float sy = (float) logoHaleHeight / logoHeight;
        m.setScale(sx, sy);// 设置缩放信息
        Bitmap newLogoBitmap = Bitmap.createBitmap(logoBitmap, 0, 0, logoWidth,
                logoHeight, m, false);
        int newLogoWidth = newLogoBitmap.getWidth();
        int newLogoHeight = newLogoBitmap.getHeight();
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//设置容错级别,H为最高
        hints.put(EncodeHintType.MAX_SIZE, LOGO_WIDTH_MAX);// 设置图片的最大值
        hints.put(EncodeHintType.MIN_SIZE, LOGO_WIDTH_MIN);// 设置图片的最小值
        hints.put(EncodeHintType.MARGIN, 2);//设置白色边距值
        // 生成二维矩阵,编码时指定大小,不要生成了图片以后再进行缩放,这样会模糊导致识别失败
        BitMatrix matrix = new MultiFormatWriter().encode(content,
                BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_WIDTH, hints);
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        int halfW = width / 2;
        int halfH = height / 2;
        // 二维矩阵转为一维像素数组,也就是一直横着排了
        int[] pixels = new int[width * height];
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
            /*
                 * 取值范围,可以画图理解下  
                 * halfW + newLogoWidth / 2 - (halfW - newLogoWidth / 2) = newLogoWidth
                 * halfH + newLogoHeight / 2 - (halfH - newLogoHeight) = newLogoHeight
                 */
                if (x > halfW - newLogoWidth / 2&& x < halfW + newLogoWidth / 2
                        && y > halfH - newLogoHeight / 2 && y < halfH + newLogoHeight / 2) {// 该位置用于存放图片信息
                    /*
                     *  记录图片每个像素信息
                     *  halfW - newLogoWidth / 2 < x < halfW + newLogoWidth / 2 
                     *  --> 0 < x - halfW + newLogoWidth / 2 < newLogoWidth
                     *   halfH - newLogoHeight / 2  < y < halfH + newLogoHeight / 2
                     *   -->0 < y - halfH + newLogoHeight / 2 < newLogoHeight
                     *   刚好取值newLogoBitmap。getPixel(0-newLogoWidth,0-newLogoHeight);
                     */
                    pixels[y * width + x] = newLogoBitmap.getPixel(
                            x - halfW + newLogoWidth / 2, y - halfH + newLogoHeight / 2);
                } else {
                    pixels[y * width + x] = matrix.get(x, y) ? BLACK: WHITE;// 设置信息
                }
            }
        }
        Bitmap bitmap = Bitmap.createBitmap(width, height,
                Bitmap.Config.ARGB_8888);
        // 通过像素数组生成bitmap,具体参考api
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return bitmap;
    }
}


bitmap工具类 ----------------->>这个是在网上找的

package com.puti.getknowledge.utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by Administrator on 2017/12/26.
 */

public class BitmapUtils {
    private static final String TAG ="BitmapUtils=====>>" ;

    /**
     * 图片的缩放方法
     *
     * @param bitmap  :源图片资源
     * @param maxSize :图片允许最大空间  单位:KB
     * @return
     */
    public static Bitmap getZoomImage(Bitmap bitmap, double maxSize) {
        if (null == bitmap) {
            return null;
        }
        if (bitmap.isRecycled()) {
            return null;
        }

        // 单位:从 Byte 换算成 KB
        double currentSize = bitmapToByteArray(bitmap, false).length / 1024;
        // 判断bitmap占用空间是否大于允许最大空间,如果大于则压缩,小于则不压缩
        while (currentSize > maxSize) {
            // 计算bitmap的大小是maxSize的多少倍
            double multiple = currentSize / maxSize;
            // 开始压缩:将宽带和高度压缩掉对应的平方根倍
            // 1.保持新的宽度和高度,与bitmap原来的宽高比率一致
            // 2.压缩后达到了最大大小对应的新bitmap,显示效果最好
            bitmap = getZoomImage(bitmap, bitmap.getWidth() / Math.sqrt(multiple), bitmap.getHeight() / Math.sqrt(multiple));
            currentSize = bitmapToByteArray(bitmap, false).length / 1024;
        }
        return bitmap;
    }

    /**
     * 图片的缩放方法
     *
     * @param orgBitmap :源图片资源
     * @param newWidth  :缩放后宽度
     * @param newHeight :缩放后高度
     * @return
     */
    public static Bitmap getZoomImage(Bitmap orgBitmap, double newWidth, double newHeight) {
        if (null == orgBitmap) {
            return null;
        }
        if (orgBitmap.isRecycled()) {
            return null;
        }
        if (newWidth <= 0 || newHeight <= 0) {
            return null;
        }

        // 获取图片的宽和高
        float width = orgBitmap.getWidth();
        float height = orgBitmap.getHeight();
        // 创建操作图片的matrix对象
        Matrix matrix = new Matrix();
        // 计算宽高缩放率
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 缩放图片动作
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap bitmap = Bitmap.createBitmap(orgBitmap, 0, 0, (int) width, (int) height, matrix, true);
        return bitmap;
    }

    /**
     * bitmap转换成byte数组
     *
     * @param bitmap
     * @param needRecycle
     * @return
     */
    public static byte[] bitmapToByteArray(Bitmap bitmap, boolean needRecycle) {
        if (null == bitmap) {
            return null;
        }
        if (bitmap.isRecycled()) {
            return null;
        }

        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bitmap.recycle();
        }

        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        return result;
    }
    public static Bitmap getBitmapByUrl(String imageUri) {
       LogUtil.e("imageUri===>>"+imageUri);
        // 显示网络上的图片
        Bitmap bitmap = null;
        try {
            URL myFileUrl = new URL(imageUri);
            HttpURLConnection conn = (HttpURLConnection) myFileUrl
                    .openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
            is.close();
            LogUtil.e("url转bitmap完成=========>>"+imageUri);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
            LogUtil.e("url转bitmap错误OutOfMemoryError=========>>"+e.toString());
            bitmap = null;
        } catch (IOException e) {
            e.printStackTrace();
            LogUtil.e("url转bitmap错误IOException=========>>"+e.toString());
            bitmap = null;
        }
        return bitmap;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值