android多图拼接长图并合理显示

以前说过了 重叠部分图片合成,今天说一下

 canvas.drawBitmap拼接长图

先上效果gif


需求:多图拼接长图,长图大小 宽度为屏幕,高度自己不变形成比例

核心源码1.:

     final int mScreenWidth = getResources().getDisplayMetrics().widthPixels;

        LogUtil.log("mScreenWidth---" + mScreenWidth);
        new AsyncTask<List<String>, Void, Bitmap>() {
            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                showMyDialog();
            }

            @Override
            protected Bitmap doInBackground(List<String>... lists) {
                List<String> list = lists[0];
                Bitmap last = null;
                for (int i = 0; i < list.size(); i++) {
                    if (last == null) {
                        last = PhotoUtils.comp(BitmapFactory.decodeFile(list.get(0)));
                    } else {
                        last = PhotoUtils.newBitmap(mScreenWidth, last, PhotoUtils.comp(BitmapFactory.decodeFile(list.get(i))));
                    }
                }
                return last;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                dismissMyDialog();
      
                ivLong.setImageBitmap(bitmap);
              
           
            }
        }.execute(pathList);

1.压缩到不崩溃的加载质量

  //图片按比例大小压缩方法(根据Bitmap图片压缩)
    public static Bitmap comp(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        if (baos.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 50, baos);//这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        float hh = 800f;//这里设置高度为800f
        float ww = 480f;//这里设置宽度为480f
        //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
 .       bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩
    }




    //一、质量压缩法
    public static Bitmap compressImage(Bitmap image) {


        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
        return bitmap;
    }

2.具体拼接方法基本原理(下面有进一步优化)

 public static Bitmap newBitmap(int width, Bitmap bit1, Bitmap bit2) {
        if (width <= 0) {
            return null;
        }

        int h1 =  bit1.getHeight() * width / bit1.getWidth();
        int h2 = bit2.getHeight() * width / bit2.getWidth();
        int height = h1 + h2; //缩放到屏幕宽度时候 合成后的总高度
        //创建一个空的Bitmap(内存区域),宽度等于第一张图片的宽度,高度等于两张图片高度总和
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        //缩放到指定大小的新bitmap
        Bitmap newSizeBitmap1 = getNewSizeBitmap(bit1, width, h1);
        Bitmap newSizeBitmap2 = getNewSizeBitmap(bit2, width, h2);

        //将bitmap放置到绘制区域,并将要拼接的图片绘制到指定内存区域
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(newSizeBitmap1, 0, 0, null);
        canvas.drawBitmap(newSizeBitmap2, 0, h1, null);
        return bitmap;
    }
 

//进行优化后的合成方法

/**
 * 以第一个图为准
 * 优化算法  1.图片不需要铺满,只需要以统一合适的宽度。然后让imageview自己去铺满,不然长图合成长图会崩溃,这里以第一张图为例
 *2.只缩放不相等宽度的图片。已经缩放过的不需要再次缩放
 * @param bit1
 * @param bit2
 * @return
 */
public static Bitmap newBitmap(Bitmap bit1, Bitmap bit2) {
    Bitmap newBit = null;
    int width = bit1.getWidth();
    if (bit2.getWidth() != width) {
        int h2 = bit2.getHeight() * width / bit2.getWidth();
        newBit = Bitmap.createBitmap(width, bit1.getHeight() + h2, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(newBit);
        Bitmap newSizeBitmap2 = getNewSizeBitmap(bit2, width, h2);
        canvas.drawBitmap(bit1, 0, 0, null);
        canvas.drawBitmap(newSizeBitmap2, 0, bit1.getHeight(), null);
    } else {
        newBit = Bitmap.createBitmap(width, bit1.getHeight() + bit2.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(newBit);
        canvas.drawBitmap(bit1, 0, 0, null);
        canvas.drawBitmap(bit2, 0, bit1.getHeight(), null);
    }
    return newBit;
}
    public static Bitmap getNewSizeBitmap(Bitmap bitmap, int newWidth, int newHeight) {
        float scaleWidth = ((float) newWidth) / bitmap.getWidth();
        float scaleHeight = ((float) newHeight) / bitmap.getHeight();
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        Bitmap bit1Scale = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix,
                true);
        return bit1Scale;
    }

3.xml显示

    <ScrollView
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <FrameLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <ImageView
                        android:id="@+id/iv_long"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:adjustViewBounds="true"
                        android:scaleType="fitXY" />

               </FrameLayout>
    </ScrollView>

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值