App的icon颜色跟App类别的关系 Posted on Oct 23, 2018
手机里的app有一百多个吧,不太喜欢用ios的app文件夹,觉得有点难看,所以一般用页来分类,每个类别一页或者几个类别一起拼成一页。于是就很容易发现购物那一页全线飘红(无视下面的视频类)。 很容易想到这不是偶然,大家都心知肚明暖色可以激发人买买买的欲望。那么其他app呢?微信是绿色的,支付宝是蓝色的,网易云音乐是红色的,这些颜色是如何选择的?这几个app的颜色选择可能有一定的偶然性,但是一个类别比如购物类有明显暖色倾向的话,颜色的选择就不是偶然了,那么除了购物类之外其他类别有没有颜色倾向呢? 碰巧会爬虫也会opencv,刚好也知道描述视觉感觉的话可以用Lab空间计算距离……既然已经想到这一步了就来做一下吧!
大致思路就是
把App Store上的app图标按类别爬下来 选择常见的几种颜色比如红、绿、蓝、黄、品红、青作为标准色 用OpenCV分析一下图片的颜色,转换到Lab空间,计算出到哪个标准色距离最短 把结果可视化方便得出结论 爬取图片 以下是代码,加了非常详细的注释,App Store的网站非常友好哈哈哈
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 # coding:utf8 import requests from bs4 import BeautifulSoup # 浏览器请求头(大部分网站没有这个请求头会报错) headers = {'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1"} all_url = 'http://itunes.apple.com/cn/genre/ios-%E5%9B%BE%E4%B9%A6/id6018?mt=8' # 开始的URL地址 start_html = requests.get(all_url, headers=headers) # 加了头的地址 Soup = BeautifulSoup(start_html.text, 'lxml') # 解析HTML # 找到类别列表 <div id="genre-nav" class="nav"> all_lei = Soup.find('div', class_='nav').find_all('a') for lei in all_lei: # 取一个类别 lei_url = lei['href'] # 取该类别的链接 lei_html = requests.get(lei_url, headers=headers) # 加了头的地址 lei_soup = BeautifulSoup(lei_html.text, 'lxml') # 解析HTML # 找到类别网址里的app排行榜 <div id="selectedcontent" class="grid3-column"> all_app = lei_soup.find('div', class_='grid3-column').find_all('a') f = open('图书'+'.txt', 'w') # 以类别名称命名txt for a in all_app: # 取出app排行榜中的一个app title = a.get_text() # 取类别名称 print(title) app_url = a['href'] # 取出该app的链接 app_html = requests.get(app_url, headers=headers) # 加了头的地址 app_soup = BeautifulSoup(app_html.text, 'lxml') # 解析HTML # 找到app页面中的icon <div class="product-hero__media l-column small-5 medium-4 large-3 small-valign-top"> icon = app_soup.find('div',class_='product-hero__media l-column small-5 medium-4 large-3 small-valign-top').find_all('img') for img in icon: src = img['src'] print(src) f.write(src + '\n') # 将icon地址写到以类别命名的txt文件中 f.close() # 得到一个以某个类别命名的txt文件 里面有该类别240个app的icon的地址 # 得到所有类别的txt
爬完之后就得到了每个类别前240个icon图片的链接,用下载器下载下来就搞定了
分析颜色 批量读取图片 1 2 3 4 5 width = 246 height = 246 size = height * width # icon尺寸 path = '/Users/Jinnm/Desktop/pic/' dirs = os.listdir(path) # 导入该路径中的所有文件名
颜色空间转换 图片里每个像素转换
1 2 3 4 5 6 7 for i in dirs: img = cv2.imread(path + i, cv2.IMREAD_COLOR) # 导入文件 img2 = [] for j in range(0, width): for k in range(0, height): # 存储每个像素点的lab值, trans为转换函数 img2.append(trans(img[i][j][2], img[i][j][1], img[i][j][0]))
标准颜色的转换
1 2 3 4 5 6 # 设定标准的13种颜色的rgb值 rule = [[255, 0, 0], [255, 147, 0], [255, 255, 0], [0, 255, 0], [0, 255, 255], [0, 0, 255], [148, 32, 146], [255, 64, 255], [171, 69, 0], [171, 121, 66], [165, 165, 165], [0, 0, 0], [255, 255, 255]]; rule2 = []; # 储存13种颜色的lab值 for i in range(0, 13): rule2.append(trans(rule[i][0], rule[i][1], rule[i][2]));
转换函数(依照rgb转lab公式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 def trans(r,g,b): #根据公式把rgb数据转到lab def calV(V): if V <= 0.04045: return V / 12.92 else: return ((V + 0.055) / 1.055) ** 2.4 def calXYZ(R, G, B): sR = calV(R / 255.0) sG = calV(G / 255.0) sB = calV(B / 255.0) x = 100 * (0.4124564 * sR + 0.3575761 * sG + 0.1804375 * sB) y = 100 * (0.2126729 * sR + 0.7151522 * sG + 0.0721750 * sB) z = 100 * (0.0193339 * sR + 0.1191920 * sG + 0.9503041 * sB) return [x, y, z] def f(t): if t > ((6.0 / 29) ** 3): return t ** (1.0 / 3) else: return 1.0 / 3 * 29 * 29 / 6 / 6 * t + 16.0 / 116 def calLab(X, Y, Z): X_n = 94.813 Y_n = 100.000 Z_n = 107.262 L = 116 * f(Y / Y_n) - 16 a = 500 * (f(X / X_n) - f(Y / Y_n)) b = 200 * (f(Y / Y_n) - f(Z / Z_n)) return [L, a, b] R = int(r) G = int(g) B = int(b) [x, y, z] = calXYZ(R, G, B) [L, a, b] = calLab(x, y, z) return [L, a, b]
量化图片颜色 计算在lab颜色空间中与标准色的距离,将每个像素点量化到距离最小的标准色,并记录一张图片中各个标准色的像素数量
1 2 3 4 5 6 7 8 for i in range(0, width * height): dist = [] for j in range(0, 13): # 记录下像素点与13种颜色在lab颜色空间中的距离 dist.append( (img2[i][0] - rule2[j][0]) ** 2 + (img2[i][1] - rule2[j][1]) ** 2 + ( img2[i][2] - rule2[j][2]) ** 2) num = [0] * 13 pos = dist.index(min(dist)) # 读取距离最小的颜色序号作为该像素点的代表 num[pos] += 1 # 一张图中所有像素点的代表颜色的数量统计
保存结果 将结果保存到exel
1 2 3 4 5 6 7 8 import xlwt book = xlwt.Workbook(encoding='utf-8'); sheet =book.add_sheet('test'); # 建立存储数据的excel表 flag = 0; for j in range(0, 13): sheet.write(flag, j, label=num[j]); # 把统计数据写入excel表中 flag += 1; book.save('/Users/Jinnm/Desktop/result.xls'); # 保存excel表
结果大概是这个样子(13列是13种颜色)
可视化结果 刚好下个学期有可视化的课程,打算学习之后处理一下这个结果,目前先用最最普通的柱状图表示
结果分析 对结果的柱状图进行初步的分析。 发现结果跟自己预想的不太一样哈哈,原本感觉购物暖色,社交冷色,结果社交类中暖色的比例也非常高。
总体 现象一:白色在所有大类中均占最高的比例 猜测原因: 大部分icon喜欢采用白底+logo的配置,由于logo在icon中占的像素数少,导致大量的icon被归类于白色主色调。 至于为什么都喜欢采用白底,猜测是因为
白色的icon背景带来更好的融合性和统一性,以ios系统为例,自带的系列图标很多都是这个形式,那么第三方也采用这个形式会使界面比较统一协调。 白色可以为用户提供清新干净的视觉体验,去掉不必要的视觉干扰,从而更集中于logo。而五彩斑斓的杂色的图标往往容易让人有嘈杂的眩晕感。 由于颜色带来的视觉效果是互相影响的,而白色一般不影响其他颜色观感,是一个非常好的“搭色”。 现象二:暖色在统计数据中比重较高 猜测原因: 现在每个用户都有大量app排列在手机中,暖色相较于冷色往往更为显眼,用红色与黄色作为icon的主颜色会使该icon更为醒目,从而增加用户的点击使用率。
现象三:配色选取大多数少于3种 这一块目前通过这个柱状图是看不出来的,但是观察exel的表格可以发现,一个icon在很多颜色上的像素数都是0或是数值很小,数值明显特别大的颜色一般在三种以内。另一方面也说明了目前这种数据可视化的方式有很多不足。 猜测原因: icon是一个很小的图标,简洁的图案和配色会比较适合这种小区域猜测,清晰而又令人印象深刻。而且再观察之后可以发现,多种颜色一般是相近的颜色。采取色相接近的配色方案主要是为了使得icon整体观感统一和谐。
分类 在红色白色总体占比大的情况下,单纯的看一个类别的柱状图,那每一个类别都是红色白色是主要颜色了……所以分类的分析采用横向对比的方法,观察相对其他类别而言,哪些颜色比较突出,哪些颜色显得特别少。这一方面的分析目前的柱状图也很不合适,而且每张图的纵坐标比例是不一样的,所以不能直接比较高度……
种类:摄影 现象: 黑白两色的比例极高,彩色运用明显比较少,但在相对运用比较少的彩色中红色占比还是比较大的。 猜测原因: 多数的摄影app喜欢标榜个性,追求性冷淡的高端简洁风。除去这一些以外的摄影app往往是针对女性用户群的,故多用女性更偏好的红粉色调。
种类:商务 现象: 绿、青、蓝、紫的比例较高 猜测原因: 这一类冷色调的颜色往往给用户以平和安稳的感觉,会让用户更倾向去信赖。而且这些冷色调是没有性别偏好的颜色,男女中都有大量的用户群偏好这种颜色,所以这是一个非常容易使用户产生好感的颜色。
种类:社交 现象: 白色的比例较低 猜测原因: 大部分的社交软件更倾向于用彩底突出吸引力。而且相较于白底的平淡无奇,彩底更能使得这些社交软件显得活泼生动而愉悦,营造更为轻松的氛围。
种类:购物 现象: 红色比例极高 猜测原因: 红色等暖色可以给用户一种视觉上的刺激感,在使icon更具冲击力的同时,也某种程度上促进了用户的购买欲,从而促进快速消费。这也是为什么大多数快餐店会选择这类冲击性大的暖色。
总结 结果还是和自己平时的感受有挺多不一样的,看来数据是王道哈哈哈。目前最大的不足就是数据可视化,不合适的可视化使得直观地看出规律变得非常困难。