iOS图片精确提取主色调算法iOS-Palette(附源码)
源码可见:[直接点击]
1.背景
图像提取主色调来增强浸入式交互体验的场景越来越常见,如知乎网页版的个人主页,Instagram的图片色调筛选。那如何去获得一张照片的主色调呢?Google在Android.support.v7里,给出了一个叫做Palette(调色板)的方案。它的效果如下:
关于这套算法,我已经在之前的文章中给出了解析(点击查看)。算法虽好,可是它却是用Java写的,而且用了很多Android或者Java很多工具库的类。我们iOS党跟Palette之间可谓是程序员之间最远的距离:“你的源码就在那里不离不弃,我却望着不能调用的API徒增叹息”。
不过现在,咱们iOS党也有自己的Palette了!让我们调着Objective-C的API,趁着2017年WWDC的改革东风,走上通往幸福的康庄大道!
2.为什么要用Palette?
有人是否要问了,不就是提取图片主色调嘛,我遍历一遍图片的所有像素信息,然后统计一下哪个RGB值最多,不就是主色调嘛?
这种方案可不可以?并不是不可以,在一些简单的场景中,这样算的出来的效果也能差强人意。但是考虑一下这些场景:淘宝上的一张带有深色背景的商品图,夜晚的霓虹灯,如:
一排排黄的出油的ofo摆在灰色的大地上:
又或者当图片的主色调并不是纯色,而是处于渐变状态,这样就会分散RGB值,出现较大误差。所以我们很容易发现,图片的主色调往往并不是单纯的出现次数最多的RGB值。它应该符合我们人眼的习惯,是我们一眼就能辨识出来的视觉焦点。而这正是Palette真正厉害之处。
3.所以Palette做了什么?
Palette有两大特色,也分别解决了两个大问题,一是解决提取颜色是否是视觉焦点的问题,二是颜色分散的问题。
(1)怎么解决颜色视觉焦点问题?
RGB色彩模式描述了三种颜色通道,这三种通道组合在一起,便成了我们最终能看到的颜色。它能表示的颜色数目多到惊人,能涵盖人眼能感知的所有色彩范围。但是它无法表示颜色对人眼的吸引程度。那让我们回想以上两张图,我们是不是一下子就被亮丽的蓝色和黄色给吸引了?注意,我用了亮丽这个词。
那什么是亮丽?答案是色彩的饱和度,也就是鲜艳度。以及恰到好处的色彩明度,也就是色彩的亮度。以及足够多的色彩数目,也就是该颜色或者颜色族所代表的像素个数。
综合来看,就是色彩饱和度越高,越鲜艳,越能吸引眼球。适当的明度也有助于提高色彩吸引度,过低的话色彩很暗,过高的话色彩趋近白色,都会让人眼忽略。至于色彩数目就不用多言,肯定越多越好嘛!
对图片色彩模式有过研究的同学肯定能猜出来我要说什么了。没错,就是用HSL色彩模式评价提示。饱和度就是HSL中的S(saturation),明度就是HSL中的L(lightness)。Palette的给出的解法就是用颜色的S和L值以及像素个数去评价一种颜色的得分。
而为了满足不同的颜色提取需求(比如有人希望提取亮的颜色,有人希望提取饱和低的颜色),Palette把颜色目标分成了六种。高亮度的Light类,普通亮度的Normarl类,暗亮度的Dark类。高饱和的Vibrant类,低饱和的Mute类。它们自由搭配可以得出六种模式:
LIGHT_VIBRANT_MODE (高亮度高饱和类)
VIBRANT_MODE(普通亮度高饱和类)
DARK_VIBRANT_MODE(暗亮度高饱和类)
LIGHT_MUTED_MODE(高亮度低饱和类)
MUTED_MODE(普通亮度低饱和类)
DARK_MUTED_MODE(暗亮度低饱和类)
每种颜色目标模式都有自己独特的Target参数,也就是S和L越靠近这个Target值得分越高,最终再综合像素个数的得分,得分最高的颜色也就是我们在对应模式下要提取的目标颜色。
(2)怎么解决颜色分散问题?
另外一个难题就是颜色分散,毕竟RGB值完全相等的情况太少了。比如蓝天,靠近太阳的地方会更白更亮,远离太阳的地方蓝色会更纯更饱和。太分散的情况下,很容易蓝色会输给颜色相对更集中的其他颜色,如海边的长满绿色植被的山。这个时候,我们需要用一个框把这些相近却不相同的蓝色给框在一起,然后计算他们的平均颜色,来代表它们,这就是Palette中VBox的概念。进一步了解VBox,移步我之前的分析文章[点击查看]。
Palette解决了这两大问题,让识别效果变得更加精确!所以当你需要去识别图片的主色调时,别忘了Palette。
4.怎么使用iOS-Palette?
在iOS-Palette中,我采用了跟TTAVPlayer[了解更多,点击查看]一样的设计思想:“保证最小的接入成本同时保证最大的扩展性”。对于绝大部分需求,你不需要去了解PaletteTarget,什么高亮度低饱和这样的概念,你只需要调用这些简单的API:
即可获得回调:
但是当你需要更多的颜色模式时,你可以使用
并且还可以使用 | 分隔符去满足不同的搭配需求,当你需要所有模式的下的目标颜色时,请使用:ALL_MODE_PALETTE,快捷获取所有模式的颜色。这些数据将会在回调Block中的allModeColorDic的字典中带回来。
Tips:推荐颜色的逻辑是优先选VIBRANT_MODE下的颜色,如果该模式下没有识别出目标颜色,则会按照MUTE_MODE------LIGHT_VIRANT_MODE ------LIGHT_MUTE_MODE------DARK_VIBRANT_MODE------DARK_MUTE_MODE的继承顺序进行传递。
5.Demo的效果一览
1)在白色背景干扰下的表现
2)在黑暗环境下的表现
3)正常光照环境下的表现
由于每张图都有点大,更多的效果图可以点击查看:
(1)[点击查看]
(2)[点击查看]
(3)[点击查看]
(4)[点击查看]
(5)[点击查看]
(6)[点击查看]
相关文章:

jQuery UI 之 LigerUI 快速入门
LigerUI 快速开发UI框架 LigerUI 是基于jQuery 的UI框架,其核心设计目标是快速开发、使用简单、功能强大、轻量级、易扩展。简单而又强大,致力于快速打造Web前端界面解决方案,可以应用于.net,jsp,php等等web服务器环境。 LigerUI有如下主要特…

HTML5标签学习之~~~
<article> 标签 article 字面意思为“文章”。在web页面中表现为独立的内容,如一篇新闻,一篇评论,一段名言,一段联系方式。这其中包括两方面,一为整个页面的主旨内容,另外就是一些辅助内容。<arti…

将Spring Boot项目打包成jar包war包
任务一:将Spring Boot项目打包成jar包 1、在pom.xml文件中添加依赖 2、通过cmd命令行来进行打包jar包(首先进入项目的目录中) 3、进入项目中的target目录下查看包 4、使用命令执行jar包; 5、浏览器查看输出结果 任务二࿱…
手把手教你在应用里用上iOS机器学习框架Core ML
2017-06-10 Cocoa开发者社区2017年的WWDC上,苹果发布了Core ML这个机器学习框架。现在,开发者可以轻松的使用Core ML把机器学习功能集成到自己的应用里,让应用变得更加智能,给用户更牛逼的体验。 Core ML是做什么的 我们知道&…

Linux服务器安装JDK、Tomcat配置web网站
安装JDK cd /usr/java/jdk【打开目录】 tar -xvzf jdk-7u79-linux-x64.gz【解压安装包】 vi ~/.bashrc【编辑环境变量】############################export JAVA_HOME/usr/java/jdk/jdk1.7.0_79export JAVA_BIN$JAVA_HOME/binexport JAVA_LIB$JAVA_HOME/libexport CLASSPATH.…

sql help cs
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Configuration;using System.Data;using System.Data.SqlClient;using System.Collections; /// <summary> /// SQLHelper 的摘要描述 /// </summary>publ…

Spring Cloud应用开发(一:使用Eureka注册服务)
1、搭建maven父工程; 注:在MyEclipse中,创建一个Maven父工程cloud,并在工程的pom.xml中添加Spring Cloud的版本依赖等信息。 2、搭建服务端工程。 注:在父工程cloud中,创建Maven子模块ms-spring-eureka-s…
SRWebSocket源码浅析(上)
2017-06-12 涂耀辉 Cocoa开发者社区一. 前言: WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——可以通俗的解释为服务器主动发送信息给客户端。 区别于MQTT、XMPP等聊天的应用层协议,它是一个传输通讯协…

Mason 简单笔记
Mason的对象 ------------------------------- Request对象 Mason有两个全局预处理对象叫做:$r和$m $r是mod_perl的请求对象,它提供了Perl的API来执行Apache的请求。 $r->;uri #获得用户请求的地址 $r->;content_type #获得…

多级页表如何节省内存
在谈到多级页表的优势的时候,很多地方都是这么说的:32位地址空间的分页系统,如果页面大小为4KB,则每个进程可达1M个页,假设每个页表项占用4个字节,这样每个进程仅仅页表项就占用了4MB连续的内存空间。 那么…

Spring Cloud应用开发(二:实现服务间的调用)
1、搭建订单服务工程。 注:在父工程cloud中,创建Maven子模块ms-spring-eureka-server; 1.1、添加依赖,在pom文件中添加Eureka依赖; 1.2、写配置文件,在配置文件中添加Eureka服务实例的端口号、服务端地址等…

webSocket详解
前言 本文会用实例的方式,将iOS各种IM的方案都简单的实现一遍。并且提供一些选型、实现细节以及优化的建议。 注:文中的所有的代码示例,在github中都有demo: iOS即时通讯,从入门到“放弃”?(demo) 可以打…

2013多校第三场
hdu 4629 题意:给你n个三角形,问覆盖1~n次的面积各是多少,n < 50; 分析:取出所有端点和交点的x坐标,排序,然后对于每一段xi~xi1的范围的线段都是不相交的,所以组成的 面积要么是三角形&#…

React+Reflux博客实践
年初用ReactExpressMongodb写的一个简单的博客。分享给各位朋友参考。 前端:ReactReact RouterRefluxReact-BootstrapWebpack后端:Express(Node.js)Ejs(Index)Mongoose(mongodb) 博客Demo地址:http://itdotaerblog.herokuapp.comGithub Addre…

Spring Cloud应用开发(三:客户端的负载均衡)
1、Ribbon的使用 注:在石榴啊RestTemplate的方法上添加LoadBalanced注解,并在其执行方法中使用服务实例的名称即可; 1.1、添加LoadBalanced注解,在ms-spring-eureka-user工程引导类中的RestTemplate()方法…

SRWebSocket源码浅析(下)
接上文) 四. 接着来讲讲数据的读和写: 当建立连接成功后,就会循环调用这么一个方法: //读取http头部 - (void)_readHTTPHeader; { if (_receivedHTTPHeaders NULL) { //序列化的http消息 _receivedHTTPHeaders CFHTTPMessageCre…

(IOS)签名Demo
思路是将每一次按下屏幕的touch move时的点存到一个数组里,即一个数组相当于一个笔画;再将该代表笔画的数组保存到一个大数组中,每组每次touch的移动都历遍大数组和笔画数组,将点于点之间连接起来。 #import <UIKit/UIKit.h>…

debug运行可以,release运行报错的原因及修改方法
通常我们开发的程序有2种模式:Debug模式和Release模式在Debug模式下,编译器会记录很多调试信息,也可以加入很多测试代码,方便我们程序员测试,以及出现bug时的分析解决Release模式下,就没有上述那些调试信息,而且编译器也会自动优化一些代码,这样生成的程序性能是最优的,但是如果…

Spring Cloud应用开发(四:服务容错保护)
1、Spring Cloud Hystrix的使用 1.1、创建microservice-eureka-user-hystrix工程,并在其pom.xml中引入eureka和hystrix的依赖; 1.2、编写配置文件。在配置文件中添加Eureka服务实例的端口号,服务端地址等; 1.3、在工程主类Applic…

计量注册师考试一些关于期限、时间、机构的总结
1:有效期: 认证5年,基准5年,标准4年,机构授权3年,注册计量师注册证3年,制造、修理许可证3年。 提前量:标准考核提前6个月,注册计量师在有效期满前30工作日内提出申请延续…
TinyCrayon-iOS-SDK:强大到使人惊讶的 Mask 及切图工具库
原文链接:https://github.com/TinyCrayon/TinyCrayon-iOS-SDKTinyCrayon-iOS-SDK:强大到使人惊讶的 Mask 及切图工具库。# 为开源点赞# —— 由SwiftLanguage分享A smart and easy-to-use image masking and cutout SDK for mobile apps. TinyCrayon SDK…

Android之自定义AlertDialog无法监听控件
参考:http://www.cnblogs.com/511mr/archive/2011/10/21/2220253.html 要做一个自定义的弹出框,以前都是用一个Activity来实现,总觉得不是很好看,弹出的框有时候感觉有点大,所以上网查资料说,可以给AlertDi…

Spring Cloud应用开发(五:API网关服务)
1、使用Zuul构建API网关服务; 注:本服务涉及到3个工程,起作用分别如下: ms-spring-eureka-server工程:服务注册中心,端口为8761。ms-spring-eureka-order工程:服务提供者,需要启动…

多态---父指针指向子类对象(父类引用指向子类对象)
我们都知道,面向对象程序设计中的类有三大特性:继承,封装,多态,这个也是介绍类的时候,必须提到的话题,那么今天就来看一下OC中类的三大特性: 一、封装 封装就是对类中的一些字段&…
ARKit从入门到精通-ARKit工作原理及流程介绍
2017-06-15 坤小 Cocoa开发者社区转载请注明出处:http://www.jianshu.com/p/0492c7122d2f 1.1-写在前面的话 1.2-ARKit与SceneKit的关系 1.3-ARKit工作原理 1.3.1-ARSCNView与ARSession 1.3.2-ARWorldTrackingSessionConfiguration与ARFrame 1.4-ARKit工作完整流程 1…

【C语言也能干大事】第五讲 组合框控件,下拉列表
获得组合框控件的句柄HWND hwndCombo1 GetDlgItem(hwnd, IDC_COMBO1); 确定目前选项的索引 int curSel ComboBox_GetCurSel(hwndCombo1); 删除项 ComboBox_DeleteString(hwndCombo1, 2); 取得有多少项int getCount ComboBox_GetCount(hwndCombo1);TCHAR getcount[256];itoa(…

Spring Cloud应用开发(六:使用本地存储方式实现分布式配置管理 )
1、搭建Config Server; 1.1、创建配置中心工程microservice-config-server,并在其pom.xml中引入Config Server的依赖; 1.2、编写配置文件application.yml,添加服务端口号和存储属性等信息; 1.3、在scr/main/resources…

PL SQL笔记(三)
loopif credit_rating < 3 then..exit;end if; end loop; select to_char(sysdate, YYYY-MM-DD HH24:MI:SS) from dual; select cast(sysdate as timestamp) from dual; 复合类型数据 1.记录: declaretypeemp_record_typeis record(r_name emp.ename%type,r_job emp.job%typ…
iOS-仿膜拜贴纸滚动(物理仿真)
导读 简单用OC写了一个小球滚动效果; 类似平衡球. GitHub地址:https://github.com/wangliujiayou/WLBallView 欢迎Star. 膜拜滚动进入正题-(传感器) 传感器是一种感应\检测装置, 目前已经广泛应用于智能手机上,用于感应\检测设备周边的信息,不…

Redhat、centos安装配置postgresql
一.安装postgresql 本文仅以 redhat,postgresql9.4为例,使用yum方式进行介绍。 官网:http://www.postgresql.org/download/linux/redhat/ 1.下载postgresql的yum源 yum install http://yum.postgresql.org/9.4/redhat/rhel-6-x86_64/pgdg-red…