2017-12-12 15:49:20 qq_38209578 阅读数 2657
  • thinkphp5微信开发实践教程

    本课程是基于ThinkPHP5.0.1的微信开发教程,在整个课程中全部采用原理讲解和实践开发配套的方式。在该教程中还包含了源码供大家下载。代码下载地址:https://code.csdn.net/hayixia606/wechat/tree/master

    2903 人正在学习 去看看 魏永强

本文主要介绍微信小程序的模拟图片懒加载,实现的原理是通过页面预加载图片(默认图),加载完成后再显示出来原图,而非真正意义上的懒加载(跟web的懒加载还有很大的差距),只是借此提高用户体验度。

多图片懒加载

1.xml页面

<block wx:for="{{list}}" wx:key="">
    <image class='relative width-100 mgb-20 fade_in' src='{{item.cover_url}}' mode='widthFix' style='display:none' bindload="_imgOnLoad" id='{{item.cover_url}}'></image>
     <view class='tag-bg {{item.checked?"tag-bg1":""}}'></view>
     <view class='tag-text fz-30 fwb'>{{item.type_name}}</view>
     <image class='relative width-100 mgb-20 fade_in {{item.loaded?"":"loading-img"}}' src='{{item.loaded?item.cover_url:item.url}}' mode='widthFix'></image>
 </block>

2.js页面

//ajax请求数据
onLoad: function () {
    var that = this
    var page = that.data.page
    wx.request({
      url: request_url,
      data: {
        'signature': signature,
        'page':1,
        'pageSize': 2
      },
      success: function (res) {
        let list = res.data.content
        for (var i = 0; i < list.length; i++) {
          list[i].url = "../../img/771.gif" //用json的格式创建url,作为加载过度图片
        }
        that.setData({
          list: list,
        })
      }
    })
  },

//监听图片加载页面
 _imgOnLoad: function (e) {
    // console.log(e)
    var loadedUrl = e.target.id
    let that = this
    let list = that.data.list
    for (var i = 0; i < list.length; i++) {
      if (list[i].cover_url == loadedUrl) {
        list[i].loaded = true
      }
      that.setData({
        list
      })
    }
  }

tips:上述数据加载的代码为get的方式,需要数据加密的则选择post的方式,有需要的可以留言。

2018-05-10 23:42:52 Chailiren 阅读数 2100
  • thinkphp5微信开发实践教程

    本课程是基于ThinkPHP5.0.1的微信开发教程,在整个课程中全部采用原理讲解和实践开发配套的方式。在该教程中还包含了源码供大家下载。代码下载地址:https://code.csdn.net/hayixia606/wechat/tree/master

    2903 人正在学习 去看看 魏永强

本源码采用付费的方式向相关成员收集。

为了激励相关人员提高程序质量,为大家提供更高质量的OpenCV以及Halcon源码,因此采用付费的方式向读者出售源码。

如果感觉文章中图像处理结果满意且想获得源码,可根据文章标价付费后将转账记录截屏,发送给小编

支付任意两款源码可升级为机器视觉专业论坛公众号VIP用户,享有机器视觉专业论坛所有源码以及学习资料下载权。

                                                    

转账记录发送方式由以下三种:

    1.发送转账记录到微信公众号“机器视觉专业论坛”,小编看到后会第一时间发送下载链接及密码。

    2.发送转账记录到邮箱clr_mv@163.com,小编看到后会第一时间发送下载链接及密码。。

    3.加小编qq2021303752,向小编索取源码。


注:小编团队可根据需求定制OpenCV以及Halcon源码。


2019-06-24 20:43:38 demm868 阅读数 4
  • thinkphp5微信开发实践教程

    本课程是基于ThinkPHP5.0.1的微信开发教程,在整个课程中全部采用原理讲解和实践开发配套的方式。在该教程中还包含了源码供大家下载。代码下载地址:https://code.csdn.net/hayixia606/wechat/tree/master

    2903 人正在学习 去看看 魏永强

640?wx_fmt=gif

向AI转型的程序员都关注了这个号👇👇👇

机器学习AI算法工程  公众号:datayx

项目地址

关注微信公众号 datayx  然后回复 cv  即可获取。

AI项目体验地址 https://loveai.tech

入门篇

  1. 简介与安装(了解安装OpenCV-Python) | 番外篇1:代码性能优化

  2. 基本元素-图片(图片载入/显示/保存) | 番外篇2:无损保存和Matplotlib使用

  3. 打开摄像头(打开摄像头捕获图片/播放保存视频) | 番外篇3:滑动条

  4. 图像基本操作(访问像素点/ROI/通道分离合并/图片属性)

  5. 颜色空间转换(颜色空间转换/追踪特定颜色物体)

  6. 阈值分割(阈值分割/二值化) | 番外篇4:Otsu阈值法

  7. 图像几何变换(旋转/平移/缩放/翻转) | 番外篇5:仿射变换与透视变换

  8. 绘图功能(画线/画圆/画矩形/添加文字) | 番外篇6:鼠标绘图

挑战任务:画动态时钟

| 拓展挑战:PyQt5编写GUI界面

640?wx_fmt=gif

基础篇

  1. 图像混合(算数运算/混合/按位运算) | 番外篇7:亮度与对比度

  2. 平滑图像(卷积/滤波/模糊/降噪) | 番外篇8:卷积基础(图片边框)

  3. 边缘检测(Canny/Sobel) | 番外篇9:图像梯度

  4. 腐蚀与膨胀(形态学操作/腐蚀/膨胀/开运算/闭运算)

  5. 轮廓 (寻找/绘制轮廓)  | 番外篇10:轮廓层级

  6. 轮廓特征 (面积/周长/最小外接矩(圆)/形状匹配) | 番外篇11:凸包及更多轮廓特征

  7. 直方图(计算绘制直方图/均衡化)

  8. 模板匹配(大图中找小图)

  9. 霍夫变换(提取直线/圆)

挑战任务:车道检测


阅读过本文的人还看了以下:

不断更新资源

深度学习、机器学习、数据分析、python

 搜索公众号添加: datayx  

640?wx_fmt=jpeg

长按图片,识别二维码,点关注

AI项目体验

https://loveai.tech

640?wx_fmt=png

2016-02-01 13:25:47 yangzhaomuma 阅读数 4906
  • thinkphp5微信开发实践教程

    本课程是基于ThinkPHP5.0.1的微信开发教程,在整个课程中全部采用原理讲解和实践开发配套的方式。在该教程中还包含了源码供大家下载。代码下载地址:https://code.csdn.net/hayixia606/wechat/tree/master

    2903 人正在学习 去看看 魏永强

微信朋友圈最近出了一个模糊照片效果,一看之下很有新意。

这里就是仿微信朋友圈的一个图片模糊效果实现。使用了一个开源的FastBlur(高斯模糊——毛玻璃效果)。

实现的方法很简单,只要一句代码即可。

Bitmap bitmap= FastBlur.doBlur(BitmapFactory.decodeResource(getResources(), R.drawable.blur), 10, false);
效果如下:



FastBlur中,没有对代码做注释,这里简单解释下doBlur中三个参数的含义:

第一个:图片资源的bitmap格式;

第二个:模糊程度(权重)——取值范围从0开始的整数,一般不取过大的数。取值如10、15、25等,假如你传值1000,会导致OOM错误;

第三个:是否可复用的bitmap。一般传false即可。因为可复用的bitmap对API的level有要求,level等不符合要求,会导致出错。


看一下FastBlur的源码:

package com.example.blur_csdn;
import android.graphics.Bitmap;

/**
 * Created by paveld on 3/6/14.
 * guss
 */
public class FastBlur {

	public static Bitmap doBlur(Bitmap sentBitmap, int radius,boolean canReuseInBitmap) 
	{
		Bitmap bitmap;
		if (canReuseInBitmap) {
			//可复用视图
			bitmap = sentBitmap;
		} else {
			
			bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
		}
        /**
         * 权重为0时,原样输出。
         * 源码原来的判断值时radius<1,这里改为以下的radius<0
         * 主要是为了让权重为0时,可输出
         */
		if (radius < 0) {
			return (null);
		}

		int w = bitmap.getWidth();
		int h = bitmap.getHeight();

		int[] pix = new int[w * h];
		bitmap.getPixels(pix, 0, w, 0, 0, w, h);

		int wm = w - 1;
		int hm = h - 1;
		int wh = w * h;
		int div = radius + radius + 1;

		int r[] = new int[wh];
		int g[] = new int[wh];
		int b[] = new int[wh];
		int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
		int vmin[] = new int[Math.max(w, h)];

		int divsum = (div + 1) >> 1;
		divsum *= divsum;
		int dv[] = new int[256 * divsum];
		for (i = 0; i < 256 * divsum; i++) {
			dv[i] = (i / divsum);
		}

		yw = yi = 0;

		int[][] stack = new int[div][3];
		int stackpointer;
		int stackstart;
		int[] sir;
		int rbs;
		int r1 = radius + 1;
		int routsum, goutsum, boutsum;
		int rinsum, ginsum, binsum;

		for (y = 0; y < h; y++) {
			rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
			for (i = -radius; i <= radius; i++) {
				p = pix[yi + Math.min(wm, Math.max(i, 0))];
				sir = stack[i + radius];
				sir[0] = (p & 0xff0000) >> 16;
				sir[1] = (p & 0x00ff00) >> 8;
				sir[2] = (p & 0x0000ff);
				rbs = r1 - Math.abs(i);
				rsum += sir[0] * rbs;
				gsum += sir[1] * rbs;
				bsum += sir[2] * rbs;
				if (i > 0) {
					rinsum += sir[0];
					ginsum += sir[1];
					binsum += sir[2];
				} else {
					routsum += sir[0];
					goutsum += sir[1];
					boutsum += sir[2];
				}
			}
			stackpointer = radius;

			for (x = 0; x < w; x++) {

				r[yi] = dv[rsum];
				g[yi] = dv[gsum];
				b[yi] = dv[bsum];

				rsum -= routsum;
				gsum -= goutsum;
				bsum -= boutsum;

				stackstart = stackpointer - radius + div;
				sir = stack[stackstart % div];

				routsum -= sir[0];
				goutsum -= sir[1];
				boutsum -= sir[2];

				if (y == 0) {
					vmin[x] = Math.min(x + radius + 1, wm);
				}
				p = pix[yw + vmin[x]];

				sir[0] = (p & 0xff0000) >> 16;
				sir[1] = (p & 0x00ff00) >> 8;
				sir[2] = (p & 0x0000ff);

				rinsum += sir[0];
				ginsum += sir[1];
				binsum += sir[2];

				rsum += rinsum;
				gsum += ginsum;
				bsum += binsum;

				stackpointer = (stackpointer + 1) % div;
				sir = stack[(stackpointer) % div];

				routsum += sir[0];
				goutsum += sir[1];
				boutsum += sir[2];

				rinsum -= sir[0];
				ginsum -= sir[1];
				binsum -= sir[2];

				yi++;
			}
			yw += w;
		}
		for (x = 0; x < w; x++) {
			rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
			yp = -radius * w;
			for (i = -radius; i <= radius; i++) {
				yi = Math.max(0, yp) + x;

				sir = stack[i + radius];

				sir[0] = r[yi];
				sir[1] = g[yi];
				sir[2] = b[yi];

				rbs = r1 - Math.abs(i);

				rsum += r[yi] * rbs;
				gsum += g[yi] * rbs;
				bsum += b[yi] * rbs;

				if (i > 0) {
					rinsum += sir[0];
					ginsum += sir[1];
					binsum += sir[2];
				} else {
					routsum += sir[0];
					goutsum += sir[1];
					boutsum += sir[2];
				}

				if (i < hm) {
					yp += w;
				}
			}
			yi = x;
			stackpointer = radius;
			for (y = 0; y < h; y++) {
				// Preserve alpha channel: ( 0xff000000 & pix[yi] )
				pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16)
						| (dv[gsum] << 8) | dv[bsum];

				rsum -= routsum;
				gsum -= goutsum;
				bsum -= boutsum;

				stackstart = stackpointer - radius + div;
				sir = stack[stackstart % div];

				routsum -= sir[0];
				goutsum -= sir[1];
				boutsum -= sir[2];

				if (x == 0) {
					vmin[y] = Math.min(y + r1, hm) * w;
				}
				p = x + vmin[y];

				sir[0] = r[p];
				sir[1] = g[p];
				sir[2] = b[p];

				rinsum += sir[0];
				ginsum += sir[1];
				binsum += sir[2];

				rsum += rinsum;
				gsum += ginsum;
				bsum += binsum;

				stackpointer = (stackpointer + 1) % div;
				sir = stack[stackpointer];

				routsum += sir[0];
				goutsum += sir[1];
				boutsum += sir[2];

				rinsum -= sir[0];
				ginsum -= sir[1];
				binsum -= sir[2];

				yi += w;
			}
		}

		bitmap.setPixels(pix, 0, w, 0, 0, w, h);

		return (bitmap);
	}
}


以上就是实现高斯图片模糊的主要方法。

高斯模糊原理,可

参考:

http://www.zhihu.com/question/32232584

http://baike.baidu.com/link?url=L2-0e-mbxhZ_PFe0GFR3Spb5t82NntthEeKoWd0N6H_6gHPqgKoqZvpN8WK6VHG7rpz41oYQn_fU4caKFkkT9a


2019-05-14 09:27:00 weixin_30520015 阅读数 11
  • thinkphp5微信开发实践教程

    本课程是基于ThinkPHP5.0.1的微信开发教程,在整个课程中全部采用原理讲解和实践开发配套的方式。在该教程中还包含了源码供大家下载。代码下载地址:https://code.csdn.net/hayixia606/wechat/tree/master

    2903 人正在学习 去看看 魏永强

今天来做一个好玩的,这个脚本做出来需要一点脑洞,hh~

当然,当你可以用adb控制手机的时候,不止能干这么些,还有更多有意思的,这就需要更大的脑洞了,比如自动薅羊毛~

思路:

  1. 利用adb截手机实时图
  2. 利用python图像处理库PIL处理图片将问题和答案的那一块截出来
  3. 利用百度识图,将图片转为中文字符串
  4. 利用百度搜索,搜索已转为中文字符串的问题
  5. 统计百度返回网页源码中对应答案出现的次数,出现次数最多的则视为正确答案
  6. 继续利用adb模拟点击手机中答案位置

什么是adb?

adb即 Android Debug Bridge,我们一般简称为adb,它是一个非常强大的命令行工具,通过这个工具你能够利用电脑与你的android设备进行交互。

adb下载:百度网盘获取:链接:https://pan.baidu.com/s/1tElgryyIuKRJ3h1PPSgGLw 密码:reop

记得将解压后的工具包添加到系统变量上,这样方便你用python脚本调用它。

可以参考这篇博文:常用的adb命令

 

 

一、将手机与电脑连接上

这一步首先需要手机开启开发者模式,因为各个手机打开的方式不一样,请根据自己机型自行百度。

 

然后是将手机用usb线连接电脑,在cmd下输入adb devices

 

若有如下图的返回则手机和电脑连接成功:

 

 

 

二、按上面的思路来打码

1、 利用adb截手机实时图

2、利用python图像处理库PIL处理图片将问题和答案的那一块截出来

这两步放在一个函数里就行了

这里先说一说下面一些(left, upper, right, lower)坐标是怎么确定的

首先,从微信进入头脑王者2,开始一场比赛

将比赛的有题目图截下来,截到图片的一般大小都是(1920*1080),比如下图:

 

然后以实际尺寸打开这张图片,再用截图工具量一下所需位置的宽高(当你截图时,一般截图工具会显示将要截的像素大小),或者你有更好的方法就另说。比如下两图是我获取问题的位置(左,上,右,下)的思路,其他位置也是这样获取:

 

 

然后就确定这些坐标了~

 adb截手机实时图代码:

import os
import random
import requests
import subprocess

from PIL import Image
from aip import AipOcr
from io import BytesIO

def get_screenshot():
    process=subprocess.Popen('adb shell screencap -p',shell=True,stdout=subprocess.PIPE)
    #相对于在cmd下执行了adb shell screencap -p,将会去截手机屏幕图
    screenshot=process.stdout.read()
    #读取截到的数据
    screenshot=screenshot.replace(b'\r\n', b'\n')
    #adb直接截的图在有点的问题,以二进制替换一下字符就可以了。
    img_fb=BytesIO()
    #BytesIO操作二进制数据,因为图片是二进制文件
    img_fb.write(screenshot)
    #写入内存
    img=Image.open(img_fb)
    #在内存打开图片
    title_img=img.crop((200,420,890,790))
    #裁剪原图,对应(left, upper, right, lower)剪出来的是问题那部分图片
    answers_img=img.crop((80,960,1000,1720))
    #裁剪原图,剪出来的是答案那部分图片

    new_img=Image.new('RGBA',(920,1140))
    #新建一张图片,用来保存上面剪问题和答案部分,就是去掉了玩家头像之类的那些杂质
    new_img.paste(title_img,(0,0,690,370))
    #问题粘贴到新建的大图
    new_img.paste(answers_img,(0,380,920,1140))
    #答案粘贴到新建的大图,过滤了不必要的元素

    new_img_fb=BytesIO()
    new_img.save(new_img_fb,'png')
    #保存图片
    with open('test.png','wb') as f:
        f.write(new_img_fb.getvalue())
    return new_img_fb  #返回新生成的图片

 

3、利用百度识图,将图片转为中文字符串

到百度云注册个账号:直达

到控制台-产品服务-人工智能-文字识别创建一个文字识别的应用如下,这种普通的文字识别每月有5w次的免费次数(开通这个应用免费,不用实名认证),我感觉没什么特殊的要求的话这已经绰绰有余了。

 

创建之后要找到这个位置,待会要用到里面的key:

 

对,还要pip安装百度云的python sdk

pip install baidu-aip

详情可到这里看看:文档直达

具体的利用:

def get_word_by_image(img):
    APPID = ''
    APIKey = ''
    SecretKey = ''  #这三个都在账号里面,上面有提到
    client = AipOcr(APPID, APIKey, SecretKey)  #创建链接
    res=client.basicGeneral(img)  #将图片传过去
    return res  #识图结果

 

4、利用百度搜索,搜索已转为中文字符串的问题

5、统计百度返回网页源码中对应答案出现的次数,出现次数最多的则视为正确答案

这两个也在一个函数里~

写个简单的爬虫逻辑就行了,如下:

def baidu(question,answer):
    url='https://www.baidu.com/s'
    headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'}
    data={
        'wd':question
    }
    res=requests.get(url=url,params=data,headers=headers)
    res.encoding=res.apparent_encoding
    html=res.text
    for i in range(len(answer)):
        answer[i]=(html.count(answer[i]),answer[i],i)  #循环4次,将答案在百度返回源码中出现的次数统计出来
    answer.sort(reverse=True)  #按降序排序答案,以出现在源码中次数最高的为答案
    return answer

 

6、继续利用adb模拟点击手机中答案位置

def click(point):
    cmd='adb shell input swipe %s %s %s %s %s'%(
        point[0],
        point[1],
        point[0]+random.randint(0,3),  #swipe实际上是拖动手机,这里加randint(0,3)是为了模拟长按手机
        point[1]+random.randint(0,3),
        200  #上面4个为坐标,这个200为持续点击的时间ms为它的单位
    )
    os.system(cmd)

三、利用以上函数

config={  #配置
    '头脑王者':{
        'title':(200,420,890,790), #用来记录标题的位置
        'answers':(80,960,1000,1720),
        'point':[
            (316,993,723,1078),
            (316,1174,723,1292),
            (316,1366,723,1469),
            (316,1570,723,1657),#四个答案的位置
        ]
    }
}


def run():
    print('准备答题')
    while True:
        input('请按回车键开始答题:')
        img=get_screenshot()
        info=get_word_by_image(img.getvalue())
        if info['words_result_num']<5:
            continue
        answers=[x['words'] for x in info['words_result'][-4:]]  #提取返回的对应题目答案的中文字符串,这个与百度云返回的数据结构有关,不必深究,会用就行
        question=''.join([x['words'] for x in info['words_result'][:-4]])  #提取返回的问题的中文字符串
        res=baidu(question,answers)
        print(question)
        print(res)
        print(config['头脑王者']['point'][res[0][2]])
        click(config['头脑王者']['point'][res[0][2]])  #模拟点击

 四、总结

因为脚本有多次图像处理及连接网络的要求,所以效率会有点慢的其实。

而且也不一定对,因为是靠百度的答案,若你有题库就能快很多了。

 

 

The end~

转载于:https://www.cnblogs.com/byadmin/articles/10859991.html

没有更多推荐了,返回首页