精华内容
下载资源
问答
  • 动态 转换 头像

    2010-02-03 09:21:28
    动态转换头像! 很值得下载看看!资源免费,大家分享!!
  • 圆形头像的基本原理是将设置的资源文件转化成Bitmap,然后通过BitmapShader类将Bitmap成为Paint的渲染器,然后在onDraw()中通过canvas.drawCircle(rx,ry,radius,paint);画布上画圆,而这个圆就是形成了圆形头像。 在...
  • python多线程抓取头像图片源码附exe程序及资源包! python多线程抓取头像图片源码附exe程序及资源包! 1.使用到的库requests、etree、re、os、ThreadPool 2.网页编码为utf-8需要转码:html.encoding=“utf-8” 3....

    python多线程抓取头像图片源码附exe程序及资源包!
    python多线程抓取头像图片源码附exe程序及资源包!

    1.使用到的库requests、etree、re、os、ThreadPool
    2.网页编码为utf-8需要转码:html.encoding=“utf-8”
    3.使用xpath获取图片链接
    4.使用了多线程
    5.需要输入页面n,具体可以看动态图片
    6.头像首页为栏目页,没有页面,这里用了if判断
    7.py打包exe命令:pyinstaller -F 目录文件.py

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    
    
    # -*- coding: utf-8 -*-
    import requests
    from lxml import etree
    import re
    import os
    from multiprocessing.dummy import Pool as ThreadPool
    
    def hqlj(n):
        urls = []
        for x in range(1,n+1):
            url=f'https://www.woyaogexing.com/touxiang/index_{x}.html'
            if x==1:
                url='https://www.woyaogexing.com/touxiang/index.html'
            print(url)
            html=requests.get(url)
            html.encoding="utf-8"
            html=html.text
            con=etree.HTML(html)
            '''href=con.xpath('//div[@class="txList "]/a')
            print(href)
            for urls in href:
                print(urls.attrib['href'])'''
    
            href=con.xpath('//div[@class="txList "]/a/@href')
            print(href)
            for lj in href:
                lj=f'https://www.woyaogexing.com{lj}'
                print(lj)
                urls.append(lj)
    
            print(urls)
    
        return urls
    
    def hqtx(url):
        #url="https://www.woyaogexing.com/touxiang/qinglv/2019/800160.html"
        html=requests.get(url)
        html.encoding="utf-8"
        html=html.text
        con=etree.HTML(html)
        h1=con.xpath('//h1/text()')
        h1=h1[0]
        h1 = re.sub(r'[\|\/\<\>\:\*\?\\\"]', "_", h1)  # 剔除不合法字符
        print(h1)
        os.makedirs(f'./touxiang/{h1}/',exist_ok=True)
        imgs=con.xpath('//img[@class="lazy"]/@src')
        print(imgs)
        i=1
        for img in imgs:
            img_url=f'https:{img}'
            if 'jpeg' in img_url:
                img_name=img_url[-5:]
            else:
                img_name = img_url[-4:]
            n=str(i)
            img_name='%s%s'%(n,img_name)
            print(img_name)
            print(img_url)
            r=requests.get(img_url)
            with open(f'./touxiang/{h1}/{img_name}','ab+') as f:
                f.write(r.content)
            print(f"保存{img_name}图片成功!")
            i=i+1
    
    
    #hqlj("https://www.woyaogexing.com/touxiang/")
    
    if __name__ == '__main__':
        n=input("请输入要采集的页码数:",)
        n=int(n)
        urls=(hqlj(n))
        try:
            # 开4个 worker,没有参数时默认是 cpu 的核心数
            pool = ThreadPool()
            results = pool.map(hqtx, urls)
            pool.close()
            pool.join()
            print("采集所有头像完成!")
        except:
            print("Error: unable to start thread")
    
    
    

    在这里插入图片描述

    最后附上exe打包程序,需要的可以试试!
    链接: https://pan.baidu.com/s/12--cjhgy_emKhx5-pEg5sA 提取码: fuas
    爬取了500页数据,分享给大家吧!总共1.71g!
    链接:https://pan.baidu.com/s/1kS-wDMc9yqaRl1m2qxKfCA 提取码:trrz
    看了下有部分数据编码好像有问题,大家凑合着用吧,不想改了!

    展开全文
  • 动态加载资源要注意两点,一是所有需要通过脚本动态加载的资源,都必须放置在resources文件夹或它的子文件夹下。resources需要在 assets 文件夹中手工创建,并且必须位于 assets 的根目录 resources文件夹中的...

    动态加载资源要注意两点,一是所有需要通过脚本动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下。resources 需要在 assets 文件夹中手工创建,并且必须位于 assets 的根目录

     

    resources 文件夹中的资源,可以引用文件夹外部的其它资源,同样也可以被外部场景或资源引用到。项目构建时,除了已在 构建发布 面板勾选的场景外,resources 文件夹中的所有资源,连同它们关联依赖的 resources 文件夹外部的资源,都会被导出。

    如果一份资源仅仅是被 resources 中的其它资源所依赖,而不需要直接被 cc.loader.loadRes 调用,那么 请不要 放在 resources 文件夹里。否则会增大包体和 settings.js 的大小,并且项目中无用的资源,将无法在构建的过程中自动剔除。同时在构建过程中,JSON 的自动合并策略也将受到影响,无法尽可能将零碎的 JSON 合并起来。

     

    // 动态加载 AnimationClip

    var self = this;

    cc.loader.loadRes("test assets/anim", function (err, clip) {

    self.node.getComponent(cc.Animation).addClip(clip, "anim");

    });

     

    第二个要注意的是 Creator 相比之前的 Cocos2d-JS,资源动态加载的时候都是 异步 的,需要在回调函数中获得载入的资源。这么做是因为 Creator 除了场景关联的资源,没有另外的资源预加载列表,动态加载的资源是真正的动态加载。

    动态加载 Asset

    Creator 提供了 cc.loader.loadRes 这个 API 来专门加载那些位于 resources 目录下的 Asset。和 cc.loader.load 不同的是,loadRes 一次只能加载单个 Asset。调用时,你只要传入相对 resources 的路径即可,并且路径的结尾处 不能 包含文件扩展名。

    // 加载 Prefab cc.loader.loadRes("test assets/prefab", function (err, prefab) { var newNode = cc.instantiate(prefab); cc.director.getScene().addChild(newNode); }); // 加载 AnimationClip var self = this; cc.loader.loadRes("test assets/anim", function (err, clip) { self.node.getComponent(cc.Animation).addClip(clip, "anim"); });

    加载 SpriteFrame

    图片设置为 Sprite 后,将会在 资源管理器 中生成一个对应的 SpriteFrame。但如果直接加载 test assets/image,得到的类型将会是 cc.Texture2D。你必须指定第二个参数为资源的类型,才能加载到图片生成的 cc.SpriteFrame:

    // 加载 SpriteFrame var self = this; cc.loader.loadRes("test assets/image", cc.SpriteFrame, function (err, spriteFrame) { self.node.getComponent(cc.Sprite).spriteFrame = spriteFrame; });

    如果指定了类型参数,就会在路径下查找指定类型的资源。当你在同一个路径下同时包含了多个重名资源(例如同时包含 player.clip 和 player.psd),或者需要获取 “子资源”(例如获取 Texture2D 生成的 SpriteFrame),就需要声明类型。

    加载图集中的 SpriteFrame

    对从 TexturePacker 等第三方工具导入的图集而言,如果要加载其中的 SpriteFrame,则只能先加载图集,再获取其中的 SpriteFrame。这是一种特殊情况。

    // 加载 SpriteAtlas(图集),并且获取其中的一个 SpriteFrame // 注意 atlas 资源文件(plist)通常会和一个同名的图片文件(png)放在一个目录下, 所以需要在第二个参数指定资源类型 cc.loader.loadRes("test assets/sheep", cc.SpriteAtlas, function (err, atlas) { var frame = atlas.getSpriteFrame('sheep_down_0'); sprite.spriteFrame = frame; });

    资源释放

    loadRes 加载进来的单个资源如果需要释放,可以调用 cc.loader.releaseRes,releaseRes 可以传入和 loadRes 相同的路径和类型参数。

    cc.loader.releaseRes("test assets/image", cc.SpriteFrame); cc.loader.releaseRes("test assets/anim");

    此外,你也可以使用 cc.loader.releaseAsset 来释放特定的 Asset 实例。

    cc.loader.releaseAsset(spriteFrame);

    资源批量加载

    cc.loader.loadResDir 可以加载相同路径下的多个资源:

    // 加载 test assets 目录下所有资源 cc.loader.loadResDir("test assets", function (err, assets) { // ... }); // 加载 test assets 目录下所有 SpriteFrame,并且获取它们的路径 cc.loader.loadResDir("test assets", cc.SpriteFrame, function (err, assets, urls) { // ... });

    加载远程资源和设备资源

    在目前的 Cocos Creator 中,我们支持加载远程贴图资源,这对于加载用户头像等需要向服务器请求的贴图很友好,需要注意的是,这需要开发者直接调用 cc.loader.load。同时,如果用户用其他方式下载了资源到本地设备存储中,也需要用同样的 API 来加载,上文中的 loadRes 等 API 只适用于应用包内的资源和热更新的本地资源。下面是这个 API 的用法:

    // 远程 url 带图片后缀名 var remoteUrl = "http://unknown.org/someres.png"; cc.loader.load(remoteUrl, function (err, texture) { // Use texture to create sprite frame }); // 远程 url 不带图片后缀名,此时必须指定远程图片文件的类型 remoteUrl = "http://unknown.org/emoji?id=124982374"; cc.loader.load({url: remoteUrl, type: 'png'}, function () { // Use texture to create sprite frame }); // 用绝对路径加载设备存储内的资源,比如相册 var absolutePath = "/dara/data/some/path/to/image.png" cc.loader.load(absolutePath, function () { // Use texture to create sprite frame });

    目前的此类手动资源加载还有一些限制,对用户影响比较大的是:

    1. 原生平台远程加载不支持图片文件以外类型的资源

    2. 这种加载方式只支持图片、声音、文本等原生资源类型,不支持 SpriteFrame、SpriteAtlas、Tilemap 等资源的直接加载和解析(需要后续版本中的 AssetBundle 支持)

    3. Web 端的远程加载受到浏览器的 CORS 跨域策略限制,如果对方服务器禁止跨域访问,那么会加载失败,而且由于 WebGL 安全策略的限制,即便对方服务器允许 http 请求成功之后也无法渲染。

    资源的依赖和释放

    在加载完资源之后,所有的资源都会临时被缓存到 cc.loader 中,以避免重复加载资源时发送无意义的 http 请求,当然,缓存的内容都会占用内存,有些资源可能用户不再需要了,想要释放它们,这里介绍一下在做资源释放时需要注意的事项。

    首先最为重要的一点就是:资源之间是互相依赖的。

    比如下图,Prefab 资源中的 Node 包含 Sprite 组件,Sprite 组件依赖于 SpriteFrame,SpriteFrame 资源依赖于 Texture 资源,而 Prefab,SpriteFrame 和 Texture 资源都被 cc.loader 缓存起来了。这样做的好处是,有可能有另一个 SpriteAtlas 资源依赖于同样的一个 SpriteFrame 和 Texture,那么当你手动加载这个 SpriteAtlas 的时候,就不需要再重新请求贴图资源了,cc.loader 会自动使用缓存中的资源。

     

    在搞明白资源的相互引用之后,资源释放的问题也就呼之欲出了,当你选择释放一个 Prefab 时,我们是不会自动释放它依赖的其他资源的,因为有可能这些依赖资源还有其他的用处。所以用户在释放资源时经常会问我们,为什么我都把资源释放了,内存占用还是居高不下?原因就是真正占用内存的贴图等基础资源并不会随着你释放 Prefab 或者 SpriteAtlas 而被释放。

    接下来要介绍问题的另一个核心:JavaScript 中无法跟踪对象引用。

    在 JavaScript 这种脚本语言中,由于其弱类型特性,以及为了代码的便利,往往是不包含内存管理功能的,所有对象的内存都由垃圾回收机制来管理。这就导致 JS 层逻辑永远不知道一个对象会在什么时候被释放,这意味着引擎无法通过类似引用计数的机制来管理外部对象对资源的引用,也无法严谨得统计资源是否不再被需要了。基于以上的原因,目前 cc.loader 的设计实际上是依赖于用户根据游戏逻辑管理资源,用户可以决定在某一时刻不再需要某些资源以及它依赖的资源,立即将它们在 cc.loader 中的缓存释放。也可以选择在释放依赖资源的时候,防止部分共享资源被释放。下面是一个简单的示例:

    // 直接释放某个贴图 cc.loader.release(texture); // 释放一个 prefab 以及所有它依赖的资源 var deps = cc.loader.getDependsRecursively('prefabs/sample'); cc.loader.release(deps); // 如果在这个 prefab 中有一些和场景其他部分共享的资源,你不希望它们被释放,可以将这个资源从依赖列表中删除 var deps = cc.loader.getDependsRecursively('prefabs/sample'); var index = deps.indexOf(texture2d._uuid); if (index !== -1) deps.splice(index, 1); cc.loader.release(deps);

    最后一个值得关注的要点:JavaScript 的垃圾回收是延迟的。

    想象一种情况,当你释放了 cc.loader 对某个资源的引用之后,由于考虑不周的原因,游戏逻辑再次请求了这个资源。此时垃圾回收还没有开始(垃圾回收的时机不可控),或者你的游戏逻辑某处,仍然持有一个对于这个旧资源的引用,那么意味着这个资源还存在内存中,但是 cc.loader 已经访问不到了,所以会重新加载它。这造成这个资源在内存中有两份同样的拷贝,浪费了内存。如果只是一个资源还好,但是如果类似的资源很多,甚至不止一次被重复加载,这对于内存的压力是有可能很高的。如果观察到游戏使用的内存曲线有这样的异常,请仔细检查游戏逻辑,是否存在泄漏,如果没有的话,垃圾回收机制是会正常回收这些内存的。

    以上就是管理资源依赖和释放时需要注意的细节。

     

    转载:https://blog.csdn.net/wangdanping2012/article/details/88846348

    展开全文
  • 图像处理技术大作业 作业题目 基于图像的动态景物的监测与跟踪 作业数据 短视频背景相同一个目标运动 短视频或 5 张图片背景相同多个目标运动 3 验证数据自己提供彩色灰度图像不限 作业完成目标 动态目标的定位与...
  • 继续上一篇文章的延续,二维码生成好的,那么就把他画到海报上吧。 样例(图一是效果图,图二是... 绘制头像 绘制二维码 绘制单行文字 /** * 绘制海报文字(默认微软雅黑/PLAIN/32) * * @param graphics ...

    继续上一篇文章的延续,二维码生成好的,那么就把他画到海报上吧。

    样例(图一是效果图,图二是模板)。

    工程代码

                   

    那么这里涉及到的知识如下。

    • 绘制单文字
    • 绘制换行文字
    • 绘制头像
    • 绘制二维码

    绘制单行文字

        /**
         * 绘制海报文字(默认微软雅黑/PLAIN/32)
         * 
         * @param graphics
         *            画笔
         * @param text
         *            文本
         * @param width
         *            坐标 x
         * @param height
         *            坐标 y
         * @param color
         *            颜色
         * @param font
         *            字体
         * @return
         */
        public static Graphics2D drawText(Graphics2D graphics, String text, int width, int height, Color color, Font font) {
            // 抗锯齿
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            if (font == null) {
                font = new Font("微软雅黑", Font.PLAIN, 32);
            }
            graphics.setFont(font);
            graphics.setPaint(new Color(0, 0, 0, 64));
            // 先绘制一遍底色
            graphics.drawString(text, width, height);
            graphics.setPaint(color);
            // 再绘制一遍文字
            // 由于部分情况会出现文字模糊的情况,保险起见才出此对策。
            graphics.drawString(text, width, height);
            return graphics;
        }
    

    绘制多行文字(代码比较冗余,有更好的办法也请告知我一下)

    /**
         * 绘制海报文字(换行)
         * 
         * @param graphics
         *            画笔
         * @param text
         *            文本
         * @param width
         *            位置:x
         * @param height
         *            位置:y
         * @param lineHeight
         *            单行行高
         * @param linewidth
         *            单行行宽
         * @param color
         *            文本颜色
         * @param textSize
         *            文本字体大小
         * @param limitLineNum
         *            限制行数
         * @param backgroundWidth
         *            底背位置(多行文字绘制时,出现为单行时居中的区域宽度。)
         * @return
         */
        public static int drawTextNewLine(Graphics2D graphics, String text, int width, int height, int lineHeight,
            int lineWidth, Color color, int textSize, int limitLineNum, int backgroundWidth) {
            Font font = new Font("微软雅黑", Font.PLAIN, textSize);
            graphics.setFont(font);
            graphics.setPaint(color);
            FontRenderContext frc = graphics.getFontRenderContext();
            graphics.getFontRenderContext();
            Rectangle2D stringBounds = font.getStringBounds(text, frc);
            double fontWidth = stringBounds.getWidth();
            List<String> lineList = new ArrayList<String>();
            int lineCharCountSub = 0;
    
            // 不满一行
            if (fontWidth <= lineWidth) {
                lineList.add(text);
                if (backgroundWidth > 0) {
                    width = (backgroundWidth - Double.valueOf(fontWidth).intValue()) / 2;
                }
            } else {
                if (backgroundWidth > 0) {
                    width = (backgroundWidth - lineWidth) / 2;
                }
                // 输出文本宽度,这里就以画布宽度作为文本宽度测试
                int textWidth = lineWidth;
                // 文本长度是文本框长度的倍数
                double bs = fontWidth / textWidth;
                // 每行大概字数
                int lineCharCount = (int)Math.ceil(text.length() / bs);
                lineCharCountSub = lineCharCount;
                int beginIndex = 0;
                while (beginIndex < text.length()) {
                    int endIndex = beginIndex + lineCharCount;
                    if (endIndex >= text.length()) {
                        endIndex = text.length();
                    }
                    String lineStr = text.substring(beginIndex, endIndex);
                    Rectangle2D tempStringBounds = font.getStringBounds(lineStr, frc);
                    int tzzs = 1;
                    while (tempStringBounds.getWidth() > textWidth) {
                        lineStr = lineStr.substring(0, lineStr.length() - tzzs);
                        tempStringBounds = font.getStringBounds(lineStr, frc);
                    }
                    lineList.add(lineStr);
                    beginIndex = beginIndex + lineStr.length();
                }
            }
    
            // Color.BLACK 。字体颜色
            graphics.setPaint(color);
            if (lineHeight == 0) {
                lineHeight = 35;
            }
            // 限行
            int lineNum = lineList.size();
            if (limitLineNum != 0 && lineNum > limitLineNum) {
                lineNum = limitLineNum;
            }
            // 绘制 换行文字
            for (int i = 0; i < lineNum; i++) {
                String lineStr = lineList.get(i);
                if (lineNum >= 2 && i == lineNum - 1) {
                    if (lineStr.length() >= lineCharCountSub - 3) {
                        lineStr = lineStr.substring(0, lineStr.length() - 2) + "...";
                    }
                }
                graphics.drawString(lineStr, width, height + (i + 1) * lineHeight);
                graphics.drawString(lineStr, width, height + (i + 1) * lineHeight);
            }
            return lineNum;
        }
    

    绘制 头像(带边角圆框)

       /**
         * 绘制 头像
         * 
         * @param graphics
         * @param avatarUrl
         * @param bufferImage
         * @param x
         * @param y
         * @return
         * @throws Exception
         */
        public static Graphics2D drawAvatar(Graphics2D graphics, String avatarUrl, BufferedImage bufferImage, int x, int y)
            throws Exception {
            // 绘制头像 。
            BufferedImage logoBufferImage = null;
            if (avatarUrl.startsWith("http")) {
                logoBufferImage = Thumbnails.of(new URL(avatarUrl)).size(70, 70).asBufferedImage();
            } else {
                logoBufferImage = Thumbnails.of(new File(avatarUrl)).size(70, 70).asBufferedImage();
            }
            int height2 = logoBufferImage.getHeight();
            // 图片变圆
            int border = 2;
            Ellipse2D.Double shapeEll =
                new Ellipse2D.Double(x + border, y + border, height2 - border * 2, height2 - border * 2);
            // 抗锯齿
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.setClip(shapeEll);
            // TODO 绘制头像
            graphics.drawImage(logoBufferImage, x, y, null);
    
            // 为了防止 头像圆角之后锯齿问题。需要在头像周围画一个白框覆盖即可。
            // 需要重新获取画笔对象。
            graphics = bufferImage.createGraphics();
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            int border2 = 2;
            Stroke s = new BasicStroke(2f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
            graphics.setStroke(s);
            graphics.setColor(Color.WHITE);
            // TODO 绘制头像边框
            graphics.drawOval(x + border, y + border, height2 - border2 * 2, height2 - border2 * 2);
            return graphics;
        }


    绘制 二维码。(这个就比较简单了,没有什么过多的额外处理,直接定位位置就可以了)

      /**
         * 绘制 图片
         * 
         * @param graphics
         *            画笔
         * @param bufferImage
         *            图片资源
         * @param x
         *            坐标 x
         * @param y
         *            坐标 y
         * @return
         * @throws Exception
         */
        public static Graphics2D drawImage(Graphics2D graphics, BufferedImage bufferImage, int x, int y) throws Exception {
            graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            graphics.drawImage(bufferImage, x, y, null);
            return graphics;
        }




    OK 。

    不足之处还请留言探讨。

    部分代码参考前人分享的资料,笔者只是做了实践运用和整理。




     





     

    展开全文
  • 更换头像

    2019-09-24 16:49:45
    更换头像的功能基本在每个app都有的,而且是最基本的,我前段时间做了下项目中的更换头像功能,记录下遇到的坑 android 7.0之后需要动态申请权限 Android 7.0 file://开头的被认为是不合法的uri,需要转成content:/...

    更换头像的功能基本在每个app都有的,而且是最基本的,我前段时间做了下项目中的更换头像功能,记录下遇到的坑

    • android 7.0之后需要动态申请权限
    • Android 7.0 file://开头的被认为是不合法的uri,需要转成content://形式的uri

    第一个坑,权限问题

    如果您的应用在其清单中列出正常权限(即,不会对用户隐私或设备操作造成很大风险的权限),系统会自动授予这些权限。如果您的应用在其清单中列出危险权限(即,可能影响用户隐私或设备正常操作的权限),系统会要求用户明确授予这些权限。Android 发出请求的方式取决于系统版本,而系统版本是应用的目标:

    • 如果设备运行的是 Android 6.0(API 级别 23)或更高版本,并且应用的 targetSdkVersion 是 23 或更高版本,则应用在运行时向用户请求权限。用户可随时调用权限,因此应用在每次运行时均需检查自身是否具备所需的权限。
    • 如果设备运行的是 Android 5.1(API 级别 22)或更低版本,并且应用的 targetSdkVersion 是 22 或更低版本,则系统会在用户安装应用时要求用户授予权限。如果将新权限添加到更新的应用版本,系统会在用户更新应用时要求授予该权限。用户一旦安装应用,他们撤销权限的唯一方式是卸载应用。

    系统权限分类:

    • 正常权限涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。例如,设置时区的权限就是正常权限。如果应用声明其需要正常权限,系统会自动向应用授予该权限。
    • 危险权限涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如,能够读取用户的联系人属于危险权限。如果应用声明其需要危险权限,则用户必须明确向应用授予该权限。

    当你进行拍照和从相册中选图片的时候,都需要一个读和写的权限即Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,

    申请权限逻辑:

    判断用户是否进行过授权

    1.没有授权
    	1.授权被拒绝过,则弹出弹窗引导用户进行授权
    	2.授权没有被拒绝过,则弹出系统请求权限的弹窗即可
    2.已经授权,则按照业务流程继续往下走
    

    具体代码如下:

    /**
             * 检查并且获取权限
             *
             * @param context              上下文
             * @param permissionParms      申请权限参数
             * @param requestCode          回调code
             * @param needShowCustomDialog 是否需要弹自定义对话框
             * @return
             */
            fun checkAndRequestPermission(context : Context, permissionParms : String ,requestCode : Int, needShowCustomDialog : Boolean) : Boolean {
                //用来记录是否向系统申请过权限
                val isInvokedSysMethod = SPUtil.getInstance().getBoolean(PERMISSION_PREFIX + permissionParms, false)
                try {
                    val permission = ContextCompat.checkSelfPermission(context, permissionParms)
                    if (hasPermission(permission, permissionParms)) {
                        return true
                    } else {
                        /** 是否拒绝过授权  */
                        val isRejected =
                            ActivityCompat.shouldShowRequestPermissionRationale(context as Activity, permissionParms)
                        if ((isRejected || permission == PackageManager.PERMISSION_GRANTED || isInvokedSysMethod) && needShowCustomDialog) {
                            /**
                             * 1. 用户拒绝过授权
                             * 2. 系统接口判断为已经授权,但实际上没有授权的
                             */
    
                            //TODO 弹出弹窗引导用户
                        } else {
                            SPUtil.getInstance().putBoolean(PERMISSION_PREFIX + permissionParms, true)
                            ActivityCompat.requestPermissions(context as Activity, arrayOf(permissionParms), requestCode)
                        }
                        return false
                    }
                } catch (e: Exception) {
                    LogUtil.printeException(e)
                }
    
                return false
    
            }
    

    当你在检测用户是否授权的时候,会碰到一个机型适配的问题

    /**
             * 是否真的获取了权限
             *
             * @param apiPermissionResult 系统接口返回的权限结果
             * @param permissonParams     权限参数
             * @return
             */
            fun hasPermission(apiPermissionResult: Int, permissonParams: String): Boolean {
    
                /**
                 * 没有授权,直接返回false
                 */
                if (apiPermissionResult != PackageManager.PERMISSION_GRANTED) {
                    return false
                }
    
                /**
                 * EUI系统,返回接口值
                 */
                if (mIsEui) {
                    return true
                }
    
                /**
                 * 小米手机(以及zuk等其他机型),即使接口返回授权,也未必真的授权,需要通过AppOpsManager再次判断
                 */
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    val appOpsManager = CommonLib.getApp().getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
                    var opStr = AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE
                    if (TextUtils.isEmpty(opStr)) {
                        throw RuntimeException("不在监控权限池,请先添加!!!")
                    }
                    try {
                        val checkOp = appOpsManager.checkOp(opStr, Process.myUid(), CommonLib.getApp().packageName)
                        return checkOp == AppOpsManager.MODE_ALLOWED
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
    
                }
                /**
                 * 未判断到小米是否真的授权,返回接口值,出问题小米自己背锅
                 */
                return true
            }
    

    到目前为止动态申请权限问题解决了

    第二个坑就是Android 7.0,file://开头的被认为是不合法的uri,需要转成content://形式的uri,否则会报错FileUriExposedException

    1.第一步

        <provider
                       android:name="android.support.v4.content.FileProvider"
                       android:authorities="${applicationId}.fileprovider"
                       android:exported="false"
                       android:grantUriPermissions="true">
                   <meta-data
                           android:name="android.support.FILE_PROVIDER_PATHS"
                           android:resource="@xml/file_paths"/>
       </provider>
    

    2.第二 步
    file_paths
    3.第三步

    USER_HEAD_PHOTO_FILE_NAME = System.currentTimeMillis().toString() + USER_HEAD_PHOTO_FILE_NAME
            var headFile = File(Environment.getExternalStorageDirectory(), USER_HEAD_PHOTO_FILE_NAME)
            var contentUri: Uri
            var intentCamera = Intent()
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    
                if (PermissionUtil.checkAndRequestPermission(this, Manifest.permission.CAMERA, REQUEST_CAMERA, true)) {
                    //画重点
                    intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                    contentUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", headFile)
                } else {
                    return
                }
            } else {
                contentUri = Uri.fromFile(headFile)
            }
            intentCamera.action = MediaStore.ACTION_IMAGE_CAPTURE
            intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, contentUri)
            startActivityForResult(intentCamera, REQUESTCODE_TAKE)
    

    到此结束

    展开全文
  • Cocos Creator 动态加载远程图片资源

    万次阅读 2018-07-25 19:27:17
    这个问题折腾了我一个下午,很难受,想通过客户端加载远程服务器中的用户头像图片。 var url = &quot;http://localhost:8080/pic/10001.png&quot;;//图片路径 var container = this.user_photo....
  • 大家好,这我鄙人第一次真真正正的写博文。这篇文章主要是记录一下unity3d中NGUI依赖关系打包以及资源动态加载的一些事,其中文中有些内容是借鉴和参考了网上一些博主的文章,如有不足之处,希望看guan
  • 需要对每个tem的头像对象(image)动态显示对应的头像。尝试利用UGUI的图集来加载,具体实现如下: 1.首先,需要知道SpriteAtlas的功能,可以保存一些关于要打包进去的sprite的设置。(详细参数设置的意义有待...
  • PSD头像源码

    2013-07-18 13:14:29
    PSD头像源码
  • Android 头像定位图标

    千次阅读 2018-05-04 09:12:05
    都是采取了通过头像合成头像定位图标的方式。其中可以在服务器上合成直接返回也可以在客户端上合成,由于这是针对Android的文章,自然是需要通过Android代码来实现的。话不多少,上效果。 效果 这是我之前写过...
  • 三国三头像素材包

    2013-12-15 19:00:03
    三国杀头像素材,各个三国杀的人物头像。有高清的和非高清的,都是些手机用的小图
  • 在游戏中经常需要在同一位置动态的改变静态图片或是动画,以下就介绍几种常用的方法 1 sprite精灵 sprite精灵是由display.newSprite()而来 这类精灵在替换的时候需要setTexture(arg) arg是texture对象,这个对象可以...
  • Navigation Drawer Activity设置头像

    千次阅读 2016-09-05 12:07:54
    一般更换头像,所需要实现的步骤有点击头像,选择拍照或相册,裁剪返回,细分如下: 弹框选择相册或拍照 解决方法:使用开源框架ActionSheet https://github.com/baoyongzhang/android-ActionSheet 或者自己写一个...
  • Android图片上传(头像裁切+原图原样)

    万次阅读 多人点赞 2015-01-18 15:21:03
    (一)头像裁切、上传服务器(效果图) 一般都是有圆形显示头像的,这里我自定义了一个ImageView,页面很干净但是看着很上档次吧! 点击头像从底部弹出一个对话框,提示用户头像来自相机或者相册,这都是常规流程。...
  • 华子钦原创YY头像源码
  • 步步分析爬取知乎用户头像

    千次阅读 2018-02-19 12:17:41
    知乎是个练习爬虫的好地方,可以找到很多资源,还能挑战一下反爬虫机制。刚开始不懂得AJAX的时候真的拿这些动态加载的网页没有办法,只好退一步,用selenium+chromedriver写一些简单的程序,这样做虽然简化了开发...
  • 校徽头像小程序后台使用spring进行搭建,只有控制层一层,在控制层中完成了请求的处理以及图片的叠加。下面看实现的具体步骤。 1、实现思路 在前面的文章校徽头像小程序前台实现中讲到了校徽制作小程序工作的基本...
  • 权限:不同的用户左边展示的菜单栏不太一样,动态路由进行非法资源拦截 二、分析 登录:输入账号、密码请求后端验证,验证通过,服务端返回一个token,拿到token,存储到cookie中,前端会根据token再去拉取一个 user...
  • 在Android开发的过程中有时候涉及到显示用户头像,不少APP上的用户头像都是显示的圆形,但是图片都是一般矩形,想要实现这种效果,使用原生的控件怕是比较难,可能会有两种想法,一种是把图片通过Bitmap进行处理,一...
  • QQ昵称和QQ头像

    千次阅读 2014-01-07 15:12:09
    导读:昨天遇到了一个奇怪的问题,就是在别人的QQ空间的转载上看到了自己的名字,头像,问我是怎么回事。晚饭后,闲来无事,想到那个问题,就打开那个看到自己头像,名字的网页(因为本人几乎不上空间,所以空间这...
  • 免费 生成 艺术字 印章 在线生成艺术字、头像等很多网站... 下来看看,简简单单几步,秀出你的个性! 本站所有资源、文档均收集自互联网,本人只负责资源的收集与推广,任何人不得下载本站资源用于违法活动,否则...
  • 1、问题描述:使用image显示头像,在更新数据库资源文件之后再次发起请求获取头像,image显示头像不发生改变,需要重新登录才能更新(或重新登陆也不更新) 2、解决办法:在image控件中src图片路径后加随机数参数,如: ...
  • Android7.0之后调用相机相册就要申请相应的... //动态权限申请库 implementation 'pub.devrel:easypermissions:1.3.0' 在MainActivity中获取权限: private String[] permissions = {Manifest.permission.CAME...
  • 1 Jcrop 是图像裁剪插件,可以实现QQ头像裁剪时的预览功能 2 具体使用方法:在前台确定选框后,将选框的尺寸数据传到后台,利用后台语言调用系统的裁剪功能,实现裁剪,再将裁剪好的图片资源链接传到前台,由前台...
  • 这个问题困扰了我好几天,安卓是可以正常显示的,那就是出现了兼容问题,网络搜索很多资源都没有相关的,最后在百度的一则帖子中找到了貌似相关的原因,测试了一下是可以展示的了 获取的头像url类似于...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,979
精华内容 3,191
关键字:

动态头像资源