如何可以得到图像的显示在 UI PickerView 组件在 swift uistackview

1617人阅读
android(12)
版本:Android4.3 API18 学习整理:liuxinming
ImageView继承自View组件,主要用于显示图片
任何Drawable对象都可使用ImageView来显示
例如图标。ImageView类可以加载各种来源的图片(如资源或图片库),需要计算图像的尺寸,比便它可以在其他布局中使用,并提供例如缩放和着色(渲染)各种显示选项。
从上面类图关系可以看出,ImageView派生了ImageButton、QuickContactBadge等组件
1、ImageButton:图片按钮
& & & ImageButton派生了ZoomButton,代表放大,缩小两个按钮
& & & & & & & & & & & & & & & android默认提供了:
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &btn_minus
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &btn_plus&
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &两个Drawable资源,只要为ZommButton的android:src属性指定以上两个属性,即可实现 放大、缩小按钮。
2、QuickContactBadge:显示关联到特定联系人的图片
更多公共方法请参阅官方API
android:adjustViewBounds
setAdjustViewBounds(boolean)
设置ImageView是否调整自己的边界来保持所显示图片的长宽比
android:baseline
setBaseline(int)
视图内基线的偏移量
android:baselineAlignBottom
setBaselineAlignBottom(boolen)
ture=图像的视图将基线对齐于其底部边缘
android:cropToPadding
setCropToPadding(boolean)
如果将该属性设为true,该组件将会被裁剪到保留该ImageView的padding
adnroid:maxheight
setMaxHeight(int)
设置ImageView的最大高度
为视图提供最大高度的可选参数。(译者注:单独使用无效,需要与setAdjustViewBounds一起使用。如果想设置图片固定大小,又想保持图片宽高比,需要如下设置:
1) 设置setAdjustViewBounds为true;
2) 设置maxWidth、MaxHeight;
3) 设置设置layout_width和layout_height为wrap_content。)
android:maxWidth
setMaxWidth(int)
设置ImageView的最大宽度
android:scaleType
setScaleType(ImageView.ScaleType)
设置所显示的图片如何缩放或移动以适应ImageView的大小
控制为了使图片适合&ImageView&的大小,应该如何变更图片大小或移动图片。一定是下列常量之一:
用矩阵来绘图
拉伸图片(不按比例)以填充View的宽高
按比例拉伸图片,拉伸后图片的高度为View的高度,且显示在View的左边
按比例拉伸图片,拉伸后图片的高度为View的高度,且显示在View的中间
按比例拉伸图片,拉伸后图片的高度为View的高度,且显示在View的右边
按原图大小显示图片,但图片宽高大于View的宽高时,截图图片中间部分显示
centerCrop
按比例放大原图直至等于某边View的宽高显示。
centerInside
当原图宽高或等于View的宽高时,按原图大小居中显示;反之将原图缩放至View的宽高居中显示。
android:src
setImageResource(int)
设置ImageView所显示的Drawable对象的ID
android:tint
setColorFilter(int,PorterDuff.Mode)
设置图像的着色颜色
奉上实例图片浏览
xml布局代码
&LinearLayout xmlns:android=&/apk/res/android&
android:orientation=&vertical&
android:layout_width=&fill_parent&
android:layout_height=&fill_parent&&
&LinearLayout
android:orientation=&horizontal&
android:layout_width=&fill_parent&
android:layout_height=&wrap_content&
android:gravity=&center&
&!-- 此处定义三个按钮 --&
&Button android:id=&@+id/button01&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:text=&@string/button01&
android:textSize=&16sp&
&Button android:id=&@+id/button02&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:text=&@string/button02&
android:textSize=&16sp&
&Button android:id=&@+id/button03&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:text=&@string/button03&
android:textSize=&16sp&
&/LinearLayout&
&!-- 定义显示图片整体的ImageView --&
&ImageView android:id=&@+id/image1&
android:layout_width=&fill_parent&
android:layout_height=&240px&
android:src=&@drawable/one&
android:scaleType=&fitCenter&
&!-- 定义显示图片局部细节的 ImageView --&
&ImageView android:id=&@+id/image2&
android:layout_width=&120dp&
android:layout_height=&120dp&
android:background=&#00f&
android:layout_marginTop=&100dp&
&/LinearLayout&
package com.example.android_
import android.os.B
import android.app.A
import android.graphics.B
import android.graphics.drawable.BitmapD
import android.view.M
import android.view.MotionE
import android.view.V
import android.view.View.OnClickL
import android.view.View.OnTouchL
import android.widget.B
import android.widget.ImageV
public class MainActivity extends Activity {
//定义一个访问图片的数组
int[] images = new int[]
R.drawable.one,
R.drawable.car,
R.drawable.weixin
//定义默认显示的图片
int currentImg = 0;
//定义图片的初始透明度
private int alpha = 255;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取增大透明度按钮对象
final Button plus = (Button) findViewById(R.id.button01);
//获取降低透明度按钮对象
final Button minus = (Button) findViewById(R.id.button02);
//获取下一张按钮对象
final Button next = (Button) findViewById(R.id.button03);
final ImageView image1 = (ImageView) findViewById(R.id.image1);
final ImageView image2 = (ImageView) findViewById(R.id.image2);
//定义查看下一张图片的监听器
next.setOnClickListener(new OnClickListener()
public void onClick(View v) {
// TODO Auto-generated method stub
//控制ImageView显示下一张
image1.setImageResource(images[++currentImg % images.length]);
//定义改变图片透明度的方法
OnClickListener listener = new OnClickListener()
public void onClick(View v) {
// TODO Auto-generated method stub
if(v == plus){
alpha +=20;
if(v == minus){
alpha -=20;
alpha = alpha&255 ? 255 :
alpha = alpha&=0 ? 0 :
//改变图片的透明度
image1.setAlpha(alpha);
//为增加透明度按钮添加监听事件
plus.setOnClickListener(listener);
//为降低透明度按钮添加监听事件
minus.setOnClickListener(listener);
* Android的手势识别
* 为image1设置触摸监听器
image1.setOnTouchListener(new OnTouchListener()
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
* 使用BitmapDrawable解析图片
BitmapDrawable bitmapDrawable = (BitmapDrawable) image1.getDrawable();
//获取第一个图片显示框中的位置(得到Bitmap)
Bitmap bitmap = bitmapDrawable.getBitmap();
//bitmap 图片实际大小与第一个ImageView的缩放比例
double scale = bitmap.getWidth() / 320.0;
//获取需要显示的图片的开始点
int x = (int) (event.getX() * scale);
int y = (int) (event.getY() * scale);
if(x + 120 & bitmap.getWidth())
x = bitmap.getWidth() - 120;
if(y + 120 & bitmap.getHeight())
y = bitmap.getHeight() - 120;
//显示图片的指定区域
//setImageBitmap()方法其实是调用了setImageDrawable()方法进行重绘。
image2.setImageBitmap(Bitmap.createBitmap(bitmap,x,y,120,120));
image2.setAlpha(alpha);
//return false说明你还没消费onTouch事件,在执行完你onTouch里面的代码之后,onTouch事件并没有结束
public boolean onCreateOptionsMenu(Menu menu) {
// I this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
调试效果:
实现功能:点击增大,降低来调整图片的透明度,点击“下一张”按钮 显示下一张图片
& & & & & & & & & & 触摸到图片时,缩放显示(或者说放大)图片的这个范围区域
& & & &&setOnTouchListener(Android的手势识别,触摸监听器)
& & & & &return false说明你还没消费onTouch事件,在执行完你onTouch里面的代码之后,onTouch事件并没有结束。就是会自动地执行Gallery这个view里onTouch代码(这个为默认).所以这就是为什么没增加你的处理的时候就只自动地调用Gallery的onTouch,若你在onTouch里面增加你的代码并且return false就会执行你的处理和默认的处理。&
& & & & &return true说明你已经消费完了onTouch事件,在执行完你的onTouch里面的代码之后,这个onTouch事件就结束了。也就是说不会再调用默认的onTouch事件了。在onTouch里面有很多种的处理比如move,down,up....,若你在move里面return false,那么接着的fling,up等后面的事件也不会处理的。&
& & & ImageView的setImageResoure()方法动态修改该ImageView所显示的图片
& & & setAlpha()设置图片透明度
& & & Bitmap部分代码
& & & & & & 用于从源位图的触碰点 截取 源位图,并将截取部分显示在第二个ImageView中。此时Bitmap类,它是一个代表位图的类,调用它的CreateBitmap()静态方法即可截取位图的指定部分。
& & & & & & 该方法返回截取区域生成的新位图
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:298655次
积分:4226
积分:4226
排名:第4979名
原创:108篇
转载:67篇
评论:101条
文章:15篇
阅读:17466
文章:21篇
阅读:19342
文章:13篇
阅读:20338
(1)(1)(1)(1)(5)(9)(5)(4)(2)(1)(2)(1)(1)(2)(3)(3)(1)(1)(3)(2)(1)(4)(1)(11)(10)(1)(2)(5)(6)(3)(4)(6)(2)(5)(17)(7)(9)(10)(22)高级UI组件(Advanced) - iOS代码库 - 开源中国社区
当前访客身份:游客 [
共有244款高级UI组件(Advanced)开源软件,第1页
UIViewExt的Swift版本 使用与OC版的UIViewExt一样简单: self.x
== self.frame.origin.x
== self.frame.origin.y
self.width == self.frame.size.width
self.height == self.frame.size.height
self.bottom
self.right
iOSImageScalerTools是一个能够自动生成图片对应2x图3x图和1x图的工具。 再也不用担心美工不给你切图了! 接入了tinypng接口
Peek 和 Pop 是 iPhone 6S 和 6S+ 新推出的一项很棒的特性,可以让你轻松通过 3D touch 实现内容预览。但是还有大概 80% 的 iOS 用户使用的是老的设备。而 PeekPop 是一个 Swift 框架,可以让你的老系统支持 Peek 和 Pop 特性。 示例代码: import PeekPop
class MyVie...
LPBadgeView是一款仿QQ新消息数的小红圈徽标Badge,橡皮筋效果的软件。 1.便利初始化 ///默认color(主题颜色)为红色
+ (LPBadgeView *)badgeWithColor:(UIColor *) 2.直接使用xib/storyboard初始化 拖入主件UIView,修改类为LPBadgeView即可,默认颜色为拖入的UIV...
LPPageViewController是一款双页分页控制器,实现两页面分页,菜单风格自定义功能的软件。
LPLevelView是一款类似AppStore评分等级条的软件。支持打分手动评级,蒙版剪切绘制自定义图标颜色。 1.支持打分手动评级,点击即可打分,同时回调打分完成block: @property (strong, nonatomic) void (^scoreBlock)(float level); 2.采用绘图渲染界面,高效流畅,可自...
LLSlideViewController 是一个新的分页控件,替代了 UIPageViewController,有效的避免了程序奔溃问题。 使用示例: [self.slideViewController setViewController:[self viewControllerAtIndex:0]
direction:LLSlideViewControllerDirectionF...
A-VibrancyView 是 iOS 模糊和镂空透明层。示例代码: vibrancyView.presentEffect() //Dispaly Light blur style with 0.5 second animation
vibrancyView.presentEffect(.Dark, animationDuration: 0) //Dsipaly Dark blur style with no fade aniam...
用于展示Banner广告,实现自动轮播,无限循环滚动功能 1.支持本地和在线banenr图片的展示(在线url 使用SDWebimage 下载); 2.添加自动展示banner 定时的控制; 3.添加自动展示banner 滚动方向展示 (左/右);
XHRadarView 是一个 iOS 仿雷达扫描界面。使用objC语言编写
FlourishUI 是一个可高度配置和 out-of-the-box-pretty UI 库。
SBCollectionView 是一个简单的 CollectionView ,可以下载图片和存储在缓存中。随笔- 228&
&&&&&&&&&&&
Github众所周知,全球最大的同性社区交友网站,在这里你可以获取任何你想要的,只要你想,只要Ta有。 从事开发几年在Github上Star了不少好的东西,当然学到了更多,在此深深的膜拜下那些开源的大神。 切入正题,下面对自己使用过或者Star过的第三方框架整理下,便于日后查阅,也方便他人借鉴,如果大家有什么好的库推荐,欢迎在本文下方评论,本篇文章不定时更新...
戳这里-----&
他人整理开源组件列表
&----点开有惊喜
&----点开有惊喜
&----点开有惊喜
&----点开有惊喜
iOS学习资源
&----点开有惊喜
开源项目源码
&&以下是简阅涉及到的几个关键技术,关键字列出来方便大家有针对性的看源代码: 全屏滑动(CWStackController) 网页抓取(TFHpple + XPath + NSRegularExpression) 夜间模式(UIAppearance + NSNotification) 离线阅读(NSURLProtocol + NSURLCache + CWObjectCache + SQLite3) 视频播放(HTML5 + JavaScript) 另外,开发期间恰逢 Swift 面世,所以里面也有少量 Swift 代码
&&部分独立组件&&方便自定义下拉刷新和上拉加载动画&&自定义 Navigation (NavigationBar相关以及NavigationController)所有元素完全自定义,通过 Pan 手势来完成类似 iOS7 的手势返回效果 。&对微博官方 SDK 的 block 封装。 更加易用,配置更简单。
个人认为,多阅读优秀的源码,对自己的水平提升还是很有帮助的,三人行必有我师
&想要在App Store中获得更多评论的最佳方式是什么?想要回答这个问题,我缺乏切实数据,但如果必须猜一下的话,我会建议问问用户。也许这样做有点老套&&大多开发者现在都有创建定制的应用内置alert。但是如果你没有时间,或者不想从头实现的话,最好用一下iRata。这个就是iRata&&一个小型库&&你可以把它放入项目中,把问卷调查什么的都忘记吧,iRate会在恰当的时候为你解决这个问题。
&&同样是提醒用户为APP评分
&&还是提醒用户评分
&提示版本更新
&操作指引框架 Swift编写
&&启动导航界面,很方便的集成
&&启动界面进入主画面动画
&&字体相关的库,设置字体样式
&&FontAwesomeKit 提供一些简单的助手类用来帮助在 iOS 上使用&。
&&收集崩溃日志,用户操作信息等,解决线上崩溃问题的神器
&&首次启动APP的新手指引
&&用这个库可以在询问用户前,就告知用户所需的系统权限,为用户带来更好的体验。接受度更高&&更多活跃用户-&更高的留存率-&数据更好-&下载率更高
&&swift下会动的启动页。
&&Swift布局框架 在代码中纯手工创建约束灰常痛苦,但幸运的是我们有了SnapKit,在board中用上它,你可以简单直观地编写约束了
&网络请求 应该不会没人用过吧
&Alamofire是一个简洁的网络库,用Swift语言编写。你是否曾经使用过AFNetworking呢?Alamofire是它的小弟。更年轻更时尚,当然(AFNetworking是用Objective-C编写的)
&&无疑是目前封装得最完善的Socket库了:支持异步TCP/UDP,支持GCD,Objective-C接口封装。。目前没有发现可以与之相比的同类产品
&&对 Alamofire的封装,很是强大
基础工具类以及Category
&&一个不错的工具包,提供各种比如编码、加密、字符串处理等等东西,还提供了一些不错的自定义控件,并且文档非常齐全
&&国外的一个大神写的很好用的分类,比较齐全
&&最近很火的YY大神,应该不用多介绍了吧
&&为基础类提供Block支持,很好用
&&很强大的日期工具类
&&针对Foundation的扩展
&&很是全面的一个扩展 iOS中的各种Objective-C Category, a collection of useful Objective-C Categories extending iOS Frameworks such as Foundation,UIKit,CoreData,QuartzCore,CoreLocation,MapKit Etc.
&&简单方便的缓存
&&webView 离线缓存库 好用
&&拼音解析,很好用
&&Chameleon是一个iOS的色彩框架。它运用现代化flat color将UIColor扩展地非常美观。我们还可以通过它运用自定义颜色创建调色板。它还有很多功用,请浏览readme。如果你想要应用美观的话,一定要把这个库加到项目里。
&&很方便集成的tabBarController框架
&&展示通知图标
&&大神模仿谷歌做的iOS原生特效控件
&&很好很强大的弹出框,多种样式满足你的需求
&&一个简单的弹出菜单
&&很方便的弹出框
&&里脊串的弹出框
&&模态弹出框,拖入两个文件就可以集成
&&比较强大
&&长按出现复制粘贴等工具view
&&酷炫的通知栏,多种通知样式,使用简单
&&和Masonry类似,对核心动画进行了封装,链式动画,强烈推荐
&&很强大不解释
&&转场动画库,跟着源码能学习到很多
&&默默的膜拜下大神,这个库很多APP都有使用到
&&看看demo你就知道干啥的了
&&用于展示Gif
&&点击按钮过渡动画,很赞
&&使动画在简单性、可链接性与声明性方面有所提高。
&&含有当前主流的几种动画框架,可以学习下源码
&&很多酷炫的加载动画,可以借鉴一下
&&富文本demo
&&很强大的Label,使用人数较多
&& 你曾经用过Slack iOS应用吗?如果你在较大的软件公司工作,也许会用过。对那些没用过的人呢?&?Slack令人激动。用到Slack的应用也是这样,尤其是用作极佳、定制的文本输入控制时。这时你有了一个现成可用在应用中的代码。自适应文本区域?试一下。手势识别、自动填充、多媒体合并?试一下。快速drop-in解决方案?试一下。其他还想要什么?SlackTextViewController 可以替代 UITableViewController & UICollectionViewController。
&&展示HTML的label
(Shimmer)[] &Facebook出品
&&文本框会随着输入字数改变高度
&&效果非常炫的文本框
&&动效不错,23333
&&为图文混排提供了一个思路
&&便捷的为你的view 添加线条。。。。简直福利啊
加载进度条
&&圆形加载进度条
&&webView 加载进度条 思路很好
&&MBProgressHUD 使用非常广泛,网上很多基于ta的封装
&&和MBProgressHUD差不多
&&对MBProgressHUD的简单封装,比较实用
消息通知提醒框,好用&加载图片
pinterest 出品 效果不错
&&使用最为广泛的加载图片第三方库
&&swift版本的SDWebImage
&&IQKeyboardManager 有swift版本了。。。。
&&常用的UI聊天文本输入框封装
&&ViewDeck 非常强大 可能需要根据自己的实际业务需求做出相应的改造
&&没用过 听说过
&&貌似不错
&&安装简便,高度定制且对手势识别良好。可以当做一个标准控件用在iOS SDK中。
NavigationBar
&&swift语言编写 上下滑动时动态隐藏标题栏
&&导航栏颜色动态改变
&&Navigation的扩展,强烈推荐
ScrollView相关
&&nicklockwood 大神出品
&&自定义cell侧滑
&&这是另一个常见于很多应用中的UI组件,苹果应该考虑在标准的iOS SDK中加入一些类似的内容。Swipeable表格cell是这个pod的最佳描述,也是最好的。
&&瀑布流学习demo
&&很方便的集成全屏返回上一层界面
&&一款日历控件,可以看看
&&DZNEmptyDataSet UITableView/UICollectionView 超类,当视图没有内容的时候用来展示空数据集。DXNEmptyDataSet 能自动工作,只需要确认 DZNEmptyDataSetSource 和用户需要返回的数据。
&&WMPageController 是一个方便形成如同网易新闻首页,控制器滑动翻页效果的控制器
&&多种样式的界面复用
&&json解析框架
&&刷新控件 MJ大神出品
&&swift下模型解析
[](/CharlinFeng/Reflect/blob/master/README_CN.md#一键字典转模型).一键字典转模型
[](/CharlinFeng/Reflect/blob/master/README_CN.md#一键模型转字典).一键模型转字典
[](/CharlinFeng/Reflect/blob/master/README_CN.md#一键plist转模型).一键plist转模型
[](/CharlinFeng/Reflect/blob/master/README_CN.md#一键归档).一键归档
&&据说很强大,还没用过,有时间研究下
&&基本项目中使用的都是这个,支持多线程操作,不错
&&各种各样的图表
&&iOS图表库!非常有用而且美观
&&一款实用的下拉列表
ReactiveCocoa(简称为RAC ),是由Github开源的一个应用于iOS和OS开发的新框架,Cocoa是苹果整套框架的简称,因此很多苹果框架喜欢以Cocoa结尾。在我们iOS开发过程中,经常会响应某些事件来处理某些业务逻辑,例如按钮的点击,上下拉刷新,网络请求,属性的变化(通过KVO)或者用户位置的变化(通过CoreLocation)。但是这些事件都用不同的方式来处理,比如action、delegate、KVO、callback等。 其实这些事件,都可以通过RAC处理,ReactiveCocoa为事件提供了很多处理方法,而且利用RAC处理事件很方便,可以把要处理的事情,和监听的事情的代码放在一起,这样非常方便我们管理,就不需要跳到对应的方法里。非常符合我们开发中高聚合,低耦合的思想。
使用JavaScript调用任何Objective-C的原生接口,获得脚本语言的能力:动态更新APP,替换项目原生代码修复bug
nimbus iOS框架 three20停止更新后的替代品
BeeFramework是一款iOS平台的MVC应用快速开发框架,使用Objective-C开发。 其早期原型曾经被应用在QQ空间 、QQ游戏大厅 等多款精品APP中。 BeeFramework 从根本上解决了iOS开发者长期困扰的各种问题,诸如:分层架构如何设计,层与层之间消息传递与处理,网络操作及缓存,异步及多线程,以及适配产品多变的UI布局需求。
如果你需要JS和原生交互,那么就使用他吧
图片处理以及展示相关
&&GPUImage是一个基于GPU图像和视频处理的开源iOS框架,提供各种各样的图像处理滤镜,并且支持照相机和摄像机的实时滤镜; 基于GPU的图像加速,因此可以加速对实时摄像头视频、电影以及image的滤镜和其它效果处理,并且能够自定义图像滤镜。另外, GPUImage支持ARC
&&背景模糊
&&图片浏览器,非常好用
&&相册选择
&&类似微信的图片选择器
&&效果不错的
&&swift下图片处理库
&&36氪开源的视频播放器
&&豆瓣开源 DOUAudioStreamer 是 iOS 和 Mac 的基于核心音频的流媒体音频播放器。
&&效率很高、所占内存很小的在线流媒体(Audio Stream)播放引擎,支持 ShoutCast 和 IceCast 流媒体协议,以及可以暂停和恢复播放。具体具备以下特色:1. 效率很高,占用内存很小(虽然是核心代码是C ,但是OBJ调用没有额外性能消耗);2. 支持 ShoutCast 和 IceCast 流媒体协议,以及标准的 HTTP 传输协议;3. 可以检测流媒体的格式;4. 支持 ShoutCast metadata5. 支持暂停和恢复流媒体播放;6. 支持背景播放;7. 支持 ID3v2;8. 支持 Podcast RSS feeds
&&PHPHub开源播放器,默默点个赞
&&可定制性比较高的播放器
&&应用内付费给我们提供了很多样本代码,而这个库丢掉了那些代码,将金钱交易相关的大多通用任务做了简单的封装。
&&应用推广界面,填写合作app的appleId即可
&&交叉推广应用是你可以免费实现的最佳市场推广策略之一。使用这个库做起来非常简单,不用都不可能&&将TAPromotee加入你的podfile中,免费配置与享受更多下载吧。
&&用于聊天App显示消息的页面,可以发送文本、声音、图片、视频等消息(不过目前的Demo似乎仅支持输入文本)。界面模仿微信App。
&&很强大的消息界面UI库
&&便捷的使用keyChain存储用户名密码等
阅读(...) 评论()学习Swift中的CoreImage(图形核心编程)
Image是一个可以让你轻松使用图形过虑器的强力框架。在这里你几乎可以获得所有不同种类的效果,比如修改图像饱和度,色彩范围,亮度等。它甚至也可以利用CPU或者GPU来处理图像数据并且它的速度很快,快到可以对视频进行实时处理。
Image过滤器也可以把图像或者视频的多重效果同时串在一起。多重的过滤器会被合并为一个单独的过滤器来应用到图像中。相对于同时处理多个不同效果来说这样做更有效率。
在本教程中,你将会获得关于CoreImage的实践经验。你将会学会一些不同的效果,并且你将会明白将物效实时应用到图像是多么的容易。
提示:在撰写本教程的时候,据我们了解由于Xcdoe6和iOS8仍然还在beta测试阶段,所以关于它们的截图不能上传。因此,在我们确认可以上传前,是不会出现关于它们的截图的。
在开始学习前,让我们先讨论下在CoreImage框架中比较重要的一些类:
·CIContext:所有的图像处理都在一个CIContext类中完成。它和CoreGraphics或者OpenGL环境比较相似。
·CIImage:这个类中保存着图像的数据。它可以使用UIImage对象,一个图像文件,或者像素数据来进行创建。
·CIFilter:该类中存在一个字典,存储定义了它所描述具体特效的各种属性。比如饱和度,颜色亮度,载切等等。
在本教程中以上的每个类你都将会使用的到。
创建项目CoreImageFun
打开Xcode使用iOS中Application下的Single View
Application模板创建一个新的项目工程。使用CoreImageFun作为项目名称,选择Iphone作为默认设备,确认当前的使用语言选择的为Swift.
下载,把这里的image.png添加到你的工程中。
下一步,打开Main.storyboard,然后拖动并添加一个新的图像视图作为现有视图的子视图。在属性面板中,设置图像视图的显示模式为(Aspect
Fit)恢复拉伸,这就就不会使图像失帧了。
下一步,确保视图大纲可见(在视图界面的左下方有一个小按钮),你可以在菜单Editor中的Show Document
Outline进行设定。
鼠标右键点击图像视图并拖曳到父视图三次,并添加下面3条限定:
1:添加Top Space to Layout
Guide限定,如果需要的话可以使用尺寸检查器来设定限定的大小为0。
2:添加Center
Horizontally限定,也设定为0。
3:添Equal Width 限定。
最后,为了限定图像视图的高度,点击鼠标右键在图像视图中拖动,并添加Aspect
Ratio限定,使用尺寸检查器将宽和高的比率为定为8:5,将值设置为0。最后,点击菜单Editor下的Resolve Auto
Layout 下的All Views in View Controller 下的Update
Frames,然后布局会按钮刚才的设定生效。
下一步,打开Assistant
Editor,请确保当前视图显示的为ViewController.swift。鼠标右键点击视图拖动到刚才打开的ViewController类中。命名为imageView,点击connect按钮。
编译并运行项目,确定到目前为止一切都是正常的,运行起来后你应当看到一个没有任何内容的屏幕显示。初始化工作完成,现在开始CoreImage!
基础的图像过滤
你即将会把一张带有简单CIFilter效果的图像显示到屏幕上来了。每当你想在图像上使用CIFilter前都需要经过下面4步:
1:创建CIImage对象。CIIMage有好几种初始化方法,有:CIImage(contenttsOfURL),CIImage(data:),CIImage(CGImage:),CIIMage(bitmapData:bytesPerRow:size:format:colorSpace:)等等。大多数情况下,都会使用CIIMage(contentsOfURL:),大多数情况下。
2:创建CIContext.CIContext是使用CPU或者GPU的基础。CIContext创建起来相对比较低效,所以重复使用比一次次的创建更好。你经常会使用到它当输出CIImage对象的时候。
3:创建CIFilter.当你创建它的时候,你需要配置一个依赖于你所使用的CIFilter数字类型的属性。
4:获得filter的输出。filter会将输出对象转换为CIImage,你可以使用CIContext把它转换为UIImage,就像下面这样.
让我们来看一下它是如何工作的。把下面的代码添加到ViewController.swift的viewDidLoad()方法中:
根据编号来逐条解释下:
1.这一行代码创建了一个NSURL对象,存储了你所使用的图像路径。
2.下一步,使用CIImage(contentsOfURL:)构造方法创建了一个CIImage对象。
3:下一步,创建CIFilter对象。CIFilter的构造方法中包括了这个过滤器的名字,还有一对用来描述过滤器的键值字典。每一个过滤器都有它自己的唯一键和值。CISepiaTone过滤器只有2个值,KCIInputImageKey和kCIInputIntensityKey,是0~1之前的浮点类型。这里设定的值为0.5。大多数过滤器如果没有设定都会使用默认的值。例外的是CIImage,必须要指定一个值。
4:使用outputImage属性会很容易的从过滤器中获得一个CIImage。一但你有了CIImage,你就需要将它转换为UIImage对象。UIImage(CIImage:)构造方法可以使用CIImage来创建一个UIImage。转换为UIImage对象后,你只需要尽早的将它显示到视图中。
编译并运行项目,你将会看到使用sepiaTone
filter效果创建的图像。
恭喜,你现在已经学会使用CIImage和CIFilters了!
使用Context创建图像
在你继续之前,你应该了解下这样的一个优化建议。
前面我曾提到过,你需要使用一个CIContext对象来创建使用CIFilter,但到目前为止还未提及过它。这表明,UIImage(CIImage:)的构造方法已经把这些工作都完成了。它自动创建了一个CIContext对象并将它应用到filter.它使得使用Core
Image API变得很容易。
但是它有一个不好的地方-每次在使用它的时候,它都会重新创建一个CIContext对象。CIContext实例意味着可重用性将大大性能。如果你相使用一个滑动条来更新filter的值,就像在本教程中之前的方法,每次更新都创建一个新的CIContext对象会使性能大大下降。
让我们适当的修改一下。删除之前在viewDidLoad()的第四步代码,使用如下代码进行替换:
同样的,让我们一行一行的来看下。
1:第一行声明了一个CIContext对象,使用它来绘制一个CGImage对象。CIContext(options:)构造方法使用NSDictionary来指定例如颜色格式,异或者是context对象会运行在CPU或者GPU。该项目中,参数设置成默认值nil就可以了。
2:context对象调用createCGImage(outputImage:fromRect:)方法将会返回一个新的CGImage的实例。
3:下一步,使用UIImage(CGImage:)构造方法像之前使用CIImage一样,直接使用CGImage创建一个新的UIImage对象。
编译并运行,运行的结果应当和之前的效果一样。
在这个例子中,使用CIContext创建filter好像没有什么特别之处。但在下一节中,当你实现了它动态修改数值的能力,你就会明白对性能的重要性了。
修改Filter的值
很好,这只是core Image
filters的开始阶段。让我们添加一个滑动条来支持实时改变filter的设置。
Main.storyboard,拖动并添加一个silder,把它添加到imageView的下面,使用centered
horizontally限定。选中当前视图,依次点击Editor \ Resolve Auto Layout Issues \
Selected Views \ Reset to Suggested Constraints,可以添加下width
constraint。
打开Assistant
Editor,显示当前ViewController.swift的视图,然后把视图中的滑动条拖动到代码中,命名为amountSlider,点击connect。
下面我们来实现滑动条动作的方法。右键点击视图中的silder选择Action并拖动到ViewControlll
class结束符}的前面。命名为amountSliderValueChanged,确保Event被设置为Value
Changed,点击connect.
每当滑动条中的数值发生变化后,你需要使用不同的值重新刷新显示图像。然后,你并不想重复这些相同的处理,这样做是很不明智也很耗时的。你需要修改类中的一些细节,使你的对象在viewDidLoad方法中可以复用。
你最想做的恐怕就是重用CIContext。如果你每次都重复创建它,程序会运行缓慢。另外的可以全局化的对象是CIFilter和CIImage。每次绘制图像都会生成一个新的CIImage,但是声明名全局变量,可以让它一起存在。
你需要在你的类中添加一些变量声明。在ViewController类中添加下面的代码:
这里需要注意一下声明这些变量的时候需要使用!符号将他们声明为隐式解析可选类型,因为在viewDidLoad方法前,你不会去初始化他们。或许你可以使用?来替换!,但是你应当清楚编译器可能会强制你将他们初始化为nil在使用他们前。隐匿解析可选类型使代码更有可读性,!无处不在。
修改viewDidLoad中的代码,将其中声明的变量修改为刚才的变量。
现在你需要实现changValue方法。在这个方法中你需要做的就是重置设置CIFilter
字典中inputIntensity的键值。
你需要通过以下几步来完成该操作。
·获得Filter输出的CIImage对象。
·将CIImage对象转换为CGImage对象。
·将CGImage对象转换为UIImage对象,并将它显示到图像视图中。
将下面的代码添加到amountSliderValueChanged(sender:):
这里说明一下,你需要将方法的参数AndObject修改为UISlider。在本方法中你只接受UISlider的属性值检索,所以你可以返回进行一下修改。如果你不想修改AnyObject的话,你需要在下一行中使用之前将它进行强制转换,否则程序会报错。
silder对象会返回一个浮点类型的数值。设定silder的默认值为min 0, max 0, default
0.5。很方便,这些设定可以正确的应用到CIFilter!
CIFilter有现成的方法可以在它的存储结构中进行设定数值。在这里,你需要使用silder返回的数值来设定inputIntensity。Swift自动将CFloat类型转换为NSNumber类型来适用于setValue(value:forKey:)。
下面的代码应该很熟悉,和之前viewDidLoad方法里的实现一样。这些代码你会反复的使用。从现在开始,你会使用
amountSliderValueChanged(sender:)
来在UIImageView中输出显示CIFilter对象。
编译并运行,使用slider会实时改变图像的灰度值!
获取相册中的照片
现在你可以快速的修改Filter的数值了,事情变的越来越有趣!但是如果你根本就不想处理这张图片该咋办?下面将使用UIImagePickerController,它可以让你在相册中选择图像,并在程序中处理。
你需要创建一个按钮,来跳转到相册视图中,打开Main.storyboard,拖动进来一个按钮在视图的右下角,将按钮命名为”Photo
Album”.像之前一样,使用 Auto Layout to Reset to Suggested
Constraints。按钮应当会在slider的下面。
打开Assistant Editor
,看到ViewControll.swift视图内容,然后鼠标右键拖动按钮到代码中结束符}的前面。连接类型为Action,将它命名为loadPhoto,确定Event为Touch
Up Inside,然后点击Connect.
使用如下代码实现loadPhoto方法:
代码的第一行实例化一个新的UIImagePickerController。然后设定图像句柄的delegate为self(就是ViewController).
这里会有一个警告。你需要把ViewController继续UIImagePickerControllerDelegate和UINavigationControllerDelegate。
还是在ViewController.swift中,使用如下代码进行修改替换:
&UIImagePickerControllerDelegate
还没有完全完成-他只是为选择的图像记录信息的占位符。不管你实现
UIImagePickerControllerDelegate
中的什么方法,你都需要在你的声明中替换UIImagePickerController。如果不这样,你可能永远只能盯着图像选择器了!
编译并运行,点击按钮。图像选择器会打开相册。
如果你是在模拟器中运行,你可能在相册中没有任何图片。在模拟器中,没有摄像头,你可以使用浏览器保存一个图像到你的相册中。打开模拟器中的浏览器,找到一张图片,保存图片。下一次你运行程序的时候,这张图片就会出现在你的相册中了。
下面这些内容是你在选择一张图片后在控制台看到的输出内容:
用户选择一个图像后会有一个图像组织的数据结构实体。这就是你想得到的内容。
现在你有办法选择图像了,如果来使用这张图像呢?
简单,只需要使用下面的代码替换delegate方法:
你需要为你选择的图像创建一个新的CIImage对象。你可以通过数据结构中的信息来获得这个UIImage对象
,在UIImagePickerControllerOriginalImage
的后面。这里最好使用一个常量因为苹果系统在后面可能会修改这个键值。
你需要使用CIImage(image:)构造方法把它转换为CIImage对象。然后将数据结构的相应值进行设定,使用其为新创建的图像。
最后一行似乎是多余的。还记得之前我说过的在changeValue方法中的代码会实时使用最新的结果更新filter的内容吗?
你需要在做一次,但你只需要调用changeValue方法。即使slider的值没有变化,你仍然可以调用这个方法来完成处理流程。你可以将它转换为自己的方法,但现在的目标是通过调用amountSliderValueChanged方法来得到正确的结果。将amountSlider
传参得到正常的值。
编译并运行,现在你可以修改相册跌任何照片!
如果你创建出了完美的灰色图像,怎么保留下它呢?你可以截个图,但是更好的办法是把他重新保存到相册中。
将处理过的图像保存到相册
为了保存处理后的图像,你需要全用AssetsLibrary
框架。在ViewController.swift开始添加如下引用代码。
当你把一个图像存储到相册的时候,你需要知道一件事情,这个存储的过程可能需要一些时间,即使你把程序关闭它也可能还在进行。
这可能是一个问题,如果你从一个程序切换到另一个,GPU的会停止处理之前的任务。如果图像还没有被存储完成,那么它可能就没有被正确的保存,不能被查看。
解决的办法就是使用CPU基础下的CIContext
进行绘制。默认的行为是使用GPU进行处理,因为它更快,但是你不想因为添加保存功能而使程序的性能下降。因为,你需要创建第二个CIContext来存储图像。模拟器中不支持这种渲染模式。
在你的程序中添加另一个新的按钮,点击它,会将你对图像做的所有改动进行存储。打开Main.storyboard,添加一个新的按钮,命名为“Save
to Album”。将按钮添加到slider的左边,添加 suggested constraints。
新的连接名称为savePhoto(sender:),如何连接前面已经讲过,添加如下代码:
上面的代码:
1:获得filter的输出CIImage对象。
2:创建一个新的基于使用CPU的CIContext对象。
3:产生CGImage对象。
4:将图像保存到相册中。
编译并运行,现在你可以将自己处理的图像永久的进行保存了。
关于图像元数据
让我们来讨论一下图像元数据。图像文件在手机有他们各自相关的各种数据,如GPS坐标、图像格式和取向。
一些特殊的内容,你需要进行保护。处理加载一张UIImage为CIImage,绘制一个CGImage,转换回UIImage,拿掉图像的元数据。为了达到保护的目标,你需要记录它然后将它传回UIImage的构造方法。
在ViewController类中添加下面的定义。
下一步,添加下面的代码
到imagePickerController(picker:didFinishPickingMediaWithInfo:),在设定beginImage的前面:
这样存储的图像会被保护。
,在amountSliderValueChanged 中添加下面一行代码 ,创建并设定UIImage:
现在,如果你有一些照片为非默认定位,他将会被保存。
还有哪些其它的Filters?
在苹果系统的CIFilter
API中有超过160种的filters,其中有126种在IOS8中可以使用。在IOS8的系统中,系统已经支持自定义图像了。
为了找出哪些filter在设备中被支持,你可以使用CIFilter的filterNamesInCategory(kCICategoryBuiltIn)方法。这个方法会返回一个可用名称的数组。
还有就是,每个filter方法都有一个叫做attributes()的方法,该方法会返回一个关于该filter的信息的数据结构。这些信息包括该filter的名称,类别,输入类型,默认的或者可接受的数值。
让我们一起在程序中添加一个方法来打出当前设备支持的filter信息。添加这个方法到ViewController方法中:
该方法使用filterNamesInCategory得到一个数组。它先打印出了filter的名称,然后将每个名称的filter进行实例化,并打印出他们各自的属性。
在viewDidLoad()方法中调用
如下方法:
你将会看到一些filters被你下面一样列出来:
WOW!,好多的filters!你可以在你的程序中对他们进行一些尝试。
更复杂一些的filter
现在我们已经看到所有IOS平台支持的滤镜,是时候创建一些复杂的滤镜了。为了做到这些,你需要创建一个专用的方法来处理CIImage。他会使用一个CIImage,将他修改为一个复古的图像,并返回一个修改后的CIImage。
添加如下的代码到ViewController:
下面一段一段的解释一下:
1:创建sepia滤镜像之前的方式一样。然后传递了一个浮点类型来设定sepia的强度效果。这个值在之后可以通过slider来进行修改。
2:为滤镜创建一个随机噪声模式如下图:
没有任何参数。之后你将使用这个随机噪声模式的纹理添加到你的复古图像中。
3:改变随机噪声模式生成。你想改变灰度,并减轻一点所以效果不那么显著。你会发现输入图像的键值会应用到输出图像的属性。使用一个输入滤镜作为输出滤镜的参数是很方便的。
4:imageByCroppingToRect()
得到一个输出的CIImage对象,将它植入矩形。在这步,你需要裁剪下CIRandomGenerator滤镜的输出因为它的范围过大。如果你没有裁剪到一些点,你会得到一个通知该滤镜没有限定的错误。CIImage并真正的包含图像数据,他们描述了一个创建他们的方法。在你调用CIContext方法前,他们是不会被真的处理的。
5:合并CIRandomGenerator滤镜的输出到speia滤镜。这个过滤器可以执行精确的操作像photoshop在图层设定高亮。ps中大多数滤镜都使用到了core
6:在混合输出带有黑色边界的图像上运行vignette滤镜。滑动条的设定比率会影响效果的强度。
7:最后 ,返回最后滤镜的输出。
这就是这个滤镜的所有操作。你现在应该对混合滤镜的形成有一个大概的了解了。不同的core
imager滤镜合并,你可以做出各种各样的效果。
下一步就是实现amountSliderValueChanged()的方法。改变这2行代码:
这行代码会使用新的效果替换sepia的效果,更复杂的滤镜方法。使用滑动条的值来设定beginImage的强度,就是在viewDidLoad方法中使用的输入CIImage对象。编译并运行,你应当会看到一个更具文雅的复古物效,使用sepia来完成,一些噪声修饰和一些渐变。
这个噪声模式可以做的更精致,但我把它就留给你来做吧,亲爱的读者。现在你已经有足够的能力来使用core
image处理图像了。疯狂吧,少年!
是以上教程的所有代码。
这个教程包含了core
image滤镜的基本使用。core
image是一个比如便捷的技术,你应当有能力可以使用它来很快的处理一些整洁的滤镜来处理图像了。
记住,当这个程序启动的时候在控制台会打印出一所有支持的滤镜。为何不来尝试一下这些滤镜呢?你可以通过查看来了解所有的滤镜使用。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 swift uistackview 的文章

 

随机推荐