美文网首页
webp图片格式转换,以及安卓使用webp图片导致的友盟分享失败

webp图片格式转换,以及安卓使用webp图片导致的友盟分享失败

作者: 不催流弊 | 来源:发表于2017-01-20 15:37 被阅读0次

    本身公司的项目,图片展示居多,服务器压力也比较大,所以使用webp格式图片也就提上了日程。webp省流量省空间,不过你要来找到现在这篇关于友盟分享失败的文章的话,相信webp格式图片也已经有过了解,就不再多说。
    google在4.0后已经支持了(4.0-4.2.1不支持无损以及透明度webp图片)webp格式 ,所以其实需要做转换的地方其实很少。但是有一些第三方SDK对webp支持的不是很好,所以有了本文。
    友盟分享实用的是自定义的 UMImage

     UMImage umImage= new UMImage(mActivity, myBitmap);
    //具体的分享方法
    new ShareAction(mActivity)
       .withTitle(title)
       .withText(text)
       .withTargetUrl(targetUrl)
       .withMedia(umImage)
       .setPlatform(shareMedia)
       .setCallback(umShareListener)
       .share();
    

    由于不是讲分享的,所以上面值列出简单的实现部分代码。
    然后可以看一下具体UMImage的方法,虽然已经混淆,但是大概可以看出来UMImage支持分享的参数类型:(a 方法就是混淆后的 UMImage构造方法)

      private void a(Context var1, Object var2) {
            if(var2 instanceof File) {
                this.e = new UMImage.FileConvertor((File)var2);
            } else if(var2 instanceof String) {
                this.e = new UMImage.UrlConvertor((String)var2);
            } else if(var2 instanceof Integer) {
                this.e = new UMImage.ResConvertor(var1, ((Integer)var2).intValue());
            } else if(var2 instanceof byte[]) {
                this.e = new UMImage.BinaryConvertor((byte[])((byte[])var2));
            } else {
                if(!(var2 instanceof Bitmap)) {
                    throw new RuntimeException("Don\'t support type");
                }
                this.e = new UMImage.BitmapConvertor((Bitmap)var2);
            }
            this.e.setConfig(new UMImage.ConvertConfig(var1));
        }
    

    可以看到支持的种类是,文件,uri(网络地址,进方法查看就是下载编译后进行设置,不再展开来说了),资源文件,byte[],其他种类会走最后的else方法,但是不是bitmap的话就会抛异常,提示不支持的分享类型。所以在我们传递一个webp的地址或者webp格式图片的时候就会报错。
    所以如果想要继续使用那就只有转换webp格式图片后使用。所以当有了图片地址后,很容易想到的就是下载然后转换为bitmap/file等类型。所以我去找了很多webp格式转换的方式,但是都要引入jar包之类的,增加安装包体积不说,使用还挺麻烦。但是安卓又已经列出来是支持webp的。
    后来找到一个简单的方式。就一句话

    Bitmap bmp = BitmapFactory.decodeFile(webp);
    

    bitmap工厂,是可以直接decode webp图片为bitmap的,就跟你放入一个jpg的图片一样使用。
    所以第一种方式

    File file=down(url);//项目的下载文件的方法,可能每个人封装的不同,我就简单描述下
    
     new Thread(){
                @Override
                public void run() {
                    Bitmap bmp = BitmapFactory.decodeFile(flie);
                    image = new UMImage(mActivity, bmp);
                }
            }.start();
    

    用这个写完之后感觉会很麻烦,还要考虑4.0之前的用户(虽然并不会有4.0前的用户了),毕竟是图片下载嘛,还要考虑图片缓存啥等乱七八糟的,不然每次一个页面每启动一次分享都要下载一张图片也是挺傻的事儿。所以想到了项目中使用的Glide,那么有没有glide自带方法来完成这次操作的呢?
    其实我们要做的,就是1 下载 2 decode为byte[]/bitmap 所以只要glide满足下载操作或者编译操作就可以了
    参考Glide downloadonly
    需要注意的是,后面一个方法

    Bitmap myBitmap = Glide.with(applicationContext)
        .load(yourUrl)
        .asBitmap()
        .centerCrop()
        .into(500, 500)
        .get()
    

    写的比较清楚的是,Although[into(int, int)]works well on background threads, note that you must not use it on the main thread. Even if the synchronous version of into did not throw an exception when used on the main thread, calling get() would block the main thread, reducing the performance and responsiveness of your app.简单说就是要写在子线程中。
    所以方法2,Glide下载文件,使用上面提到的文件方式设置。

    final FutureTarget<File> future = Glide.with(mActivity)
            .load(picUrl)
            .downloadOnly(500, 500);
        new Thread(){
            @Override
            public void run() {
                File cacheFile = null;
                try {
                    cacheFile = future.get();
                    umImage = new UMImage(mActivity, cacheFile);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    
    

    方式3,使用Glide下载并decode图片为bitmap再进行设置给友盟

    new Thread(){
        @Override
        public void run() {
            try {
                Bitmap myBitmap = Glide.with(myActivity)
                        .load(picUrl)
                        .asBitmap()
                        .centerCrop()
                        .into(500, 500)
                        .get();
                umImage= new UMImage(mActivity, myBitmap);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }.start();
    

    除此之外,需要注意的点还有,方式一,BitmapFactory.decode是一个比较耗时的操作,虽然可能写在MainThread也可能不会出错(实际上会偶尔失败),但是还是强烈建议写在子线程中。

    最后,敬业福哪里搞?

    Paste_Image.png

    相关文章

      网友评论

          本文标题:webp图片格式转换,以及安卓使用webp图片导致的友盟分享失败

          本文链接:https://www.haomeiwen.com/subject/ljnwbttx.html