在Swift中将照片滤镜与核心图像一起应用

最终产品图片
您将要创造的

核心映像框架的力量

Core Image是一种图像处理和分析技术,旨在为iOS和OS X中的静止图像和视频图像提供近乎实时的处理。Apple制作了一些出色的预制照片效果,您可以轻松地将它们用于摄影应用程序。名称,例如“即时”,“过程”,“棕褐色”,“色调”等。

核心图片参考

iOS开发人员库在Core Image Reference Collection中很好地解释了Core Image图像处理。

我建议您也查看“ 核心图像过滤器参考”页面,以获取可用CIFilter的完整列表。 请注意,并非所有这些都与iOS兼容; 其中一些仅适用于OSX。

我们将使用以下核心图像过滤器:

  • CIPhotoEffectChrome
  • CISepiaTone
  • CIPhotoEffectTransfer
  • CIPhotoEffectTonal
  • CIPhotoEffectProcess
  • CIPhotoEffectNoir
  • CIPhotoEffectInstant
  • CIPhotoEffectFade

注意: 本教程是使用Xcode 7.3和Swift 2.2编写的,并且将Deployment Target设置为8.0,因此您的应用程序也可以在较旧的设备上运行。

让我们开始吧!

创建一个项目并添加视图

打开Xcode并创建一个新项目iOS Single View Application 。 选择“ Swift”作为语言,选择“ 通用”作为设备。 在Storyboard中,您将获得一个空白的UIViewController以及两个.swift文件: ViewController.swiftAppDelegate.swift

在情节提要中选择控制器,然后在右侧面板的“ 模拟度量”下将其大小设置为iPhone 3.5英寸 。 这将帮助您调整屏幕尺寸最小的Apple设备iPhone 4S的视图。

将控制器尺寸设置为iPhone 4S

在本教程中,我们将不使用“自动布局”,因为它会弄乱iPad和iPad Pro等大型设备上的布局。 通过选择File Inspector禁用它,然后取消选中Use Auto Layout 。 然后从弹出窗口中单击“ 禁用尺寸类别”按钮。

禁用自动布局和尺寸类别

现在,从Web或Mac中找到JPEG图像,并将其拖到“项目”导航器面板中的Assets.xcassets文件夹下。 我们将其用作示例图像,可以将其应用到过滤器中。 将此文件命名为picture.jpg ; 我们稍后将在代码中将其命名。

您将不得不将一些其他视图拖到控制器中。 选择Xcode右下角的对象库,然后将UIView拖动到屏幕中央。 将视图尺寸调整为320 x 320 px,并将其水平居中。

现在,通过在对象库中找到两个UIImageView并将其拖到主UIView ,将它们添加到Storyboard中。 调整这些图像视图的大小以填充该主视图(稍后我们将介绍如何设置其自动调整大小属性)。 使用“属性”检查器面板将picture.jpg分配给第一个图像视图。

将jpg图像分配给第一个UIImageView

接下来,将UIScrollView拖到屏幕底部,并设置其宽度以适合控制器的宽度。 您还可以将UILabel添加到控制器的顶部,并将其文本设置为Filters 。 这将是您的应用程序的标题。

最后,将UIButton添加到屏幕的左上角,并使其标题为Save

设置自动调整大小和布局视图

尺寸检查器 通过单击屏幕右上角的小尺子图标可以显示面板。 现在执行此操作,然后通过选择UIButton开始编辑视图大小。 大小检查器将在屏幕上显示其x和y坐标(请记住,x在屏幕左侧为0,y在顶部为0)。 将宽度和高度设置为44像素。

设置保存按钮的大小和边距

设置按钮的自动调整大小蒙版以附加到屏幕的顶部和左侧。

现在,一个一个地选择所有其他视图,并如下调整其大小和位置:

设置标题标签大小和边距

该应用程序标题的宽度为320像素,高度为44像素,并附在屏幕顶部。

设置imageViews的大小和边距

每个图像视图的宽度和高度均为320像素。

设置ScrollView的大小和边距

最后,滚动视图(用于过滤器选项)的宽度为320像素,高度为80像素。

在.swift文件中声明视图

Xcode最好的功能之一是可以将工作空间分为两部分,并在一侧提供Storyboard,在另一侧提供Swift文件。 为了做到这一点,您必须单击Xco​​de窗口右上角的Assistant Editor图标:

助理编辑器图标

如果在Storyboard中选择了ViewController ,则右侧部分将自动显示其相对的.swift文件。 如果没有发生这种情况,您可以尝试单击swift文件顶部的水平菜单,然后将Manual切换为Automatic

在Xcode窗口的右侧找到控制器swift文件

现在,让我们将一些视图附加到ViewController.swift文件。 在“ 文档大纲”面板中,选择包含两个UIImageViewUIView ,按住Control (或鼠标右键),然后将鼠标指针拖到下面以获取视图控制器的类声明。

释放鼠标按钮,将出现一个弹出窗口。 键入名称UIView - containerView -and点击连接按钮。

您刚刚向.swift文件中添加了UIView类型的IBOutlet声明。 对其他图像视图执行相同的操作:将蓝线拖到您要声明的每个实例下方,并将第一个命名为originalImage和第二个imageToFilter 。 确保originalImage是带有picture.jpg作为图像的图像。

然后连接UIScrollView并将其命名为filtersScrollView 。 这将存储用于将滤镜应用于图片的所有按钮。

稍后我们将UIButton声明为IBAction 。 此按钮将使我们能够将过滤后的图像保存到设备的照片库中。

让我们编码!

创建一组核心图像滤镜

在Swift中,您可以通过简单地将全局变量放在class声明之外来声明全局变量,在本例中为:

class ViewController: UIViewController {

我们需要创建一个CIFilter名称数组:

var CIFilterNames = [
    "CIPhotoEffectChrome",
    "CIPhotoEffectFade",
    "CIPhotoEffectInstant",
    "CIPhotoEffectNoir",
    "CIPhotoEffectProcess",
    "CIPhotoEffectTonal",
    "CIPhotoEffectTransfer",
    "CISepiaTone"
]

如本教程开头所述,我们必须使用原始的Core Image过滤器名称,以便我们的应用程序能够识别它们。 我们将这些过滤器分配给稍后创建的按钮,这些按钮会将过滤器应用于我们的图像。

隐藏状态栏

在大多数情况下,您可能希望从屏幕上隐藏状态栏。 从Xcode 7.0开始,不再可以在Info.plist中设置状态栏的hidden属性,因此必须在viewDidLoad()上方添加此方法:

override func prefersStatusBarHidden() -> Bool {
    return true
}

创建过滤器按钮

viewDidLoad()方法是Xcode每次向您的项目添加.swift文件时创建的默认实例; 当屏幕及其所有视图加载时,将调用它。 如果您想在发生之前执行某些操作,则可以使用viewDidAppear()viewWillAppear()方法,但是我们不需要这样做。 因此,让我们在super.viewDidLoad()下面添加一些CGFloat类型的变量:

override func viewDidLoad() {
    super.viewDidLoad()
    
    var xCoord: CGFloat = 5
    let yCoord: CGFloat = 5
    let buttonWidth:CGFloat = 70
    let buttonHeight: CGFloat = 70
    let gapBetweenButtons: CGFloat = 5

需要这些值才能在我们的filtersScrollView内放置一行按钮。 如您在上面的代码中看到的, xCoord是将放置按钮的X位置, yCoord是Y位置, buttonWidthbuttonHeight是其大小, gapBetweenButtons是每个按钮之间的间隔。

现在,我们需要使用for循环实际创建按钮,该循环将复制自定义UIButton并将其基于上述值放置到filtersScrollView

将此代码放在这些CGFloat实例的正下方:

var itemCount = 0
        
    for i in 0..<CIFilterNames.count {
        itemCount = i
            
        // Button properties
        let filterButton = UIButton(type: .Custom)
        filterButton.frame = CGRectMake(xCoord, yCoord, buttonWidth, buttonHeight)
        filterButton.tag = itemCount
        filterButton.addTarget(self, action: #selector(ViewController.filterButtonTapped(_:)), forControlEvents: .TouchUpInside)
        filterButton.layer.cornerRadius = 6
        filterButton.clipsToBounds = true
        
        // CODE FOR FILTERS WILL BE ADDED HERE...

让我们看看这段代码会发生什么。 itemCount是一个变量,稍后我们将使用它来将过滤器按钮添加为filtersScrollView子视图。 您可能会注意到,我们已经使用var前缀声明了此变量。 那是因为它将被for循环修改。 如果要在Swift中声明常量,请使用let前缀,就像我们对filterButton所做的filterButton

使用Swift 2.2的新for循环语法,我们不再需要编写i++ 。 循环将通过从0计数到CIFilterNames数组的元素数量自动使i增加。

在该for循环内,我们创建一个自定义按钮,设置其CGRect值,为其分配标签,然后向其添加目标操作,该操作将调用稍后将介绍的函数: filterButtonTapped()

为了使我们的按钮看起来带有圆角,我们使用layer属性并将其角半径设置为6。然后我们将图像裁剪为包含在其边界内,否则它将覆盖圆角。

将图像添加到按钮并应用过滤器

必须在上一个注释的下方添加下一个代码段:

// Create filters for each button
        let ciContext = CIContext(options: nil)
        let coreImage = CIImage(image: originalImage.image!)
        let filter = CIFilter(name: "\(CIFilterNames[i])" )
        filter!.setDefaults()
        filter!.setValue(coreImage, forKey: kCIInputImageKey)
        let filteredImageData = filter!.valueForKey(kCIOutputImageKey) as! CIImage
        let filteredImageRef = ciContext.createCGImage(filteredImageData, fromRect: filteredImageData.extent)
        let imageForButton = UIImage(CGImage: filteredImageRef);

在这里,我们初始化CIContextCIImage以使Core Image在每个按钮将显示的originalImagepicture.jpg )上工作。 然后,我们初始化一个CIFilter类型的过滤器变量,该按钮将由每个按钮通过基于CIFilterNames数组的for循环CIFilterNames

我们的filter实例需要设置其默认状态,然后它成为图像的输入键。 然后,我们从该对象及其图像引用创建数据对象,我们将使用它们立即创建一个UIImage并将其附加到按钮。

由于我们在本教程中选择的滤镜是Apple预先制成的,因此我们不需要应用任何其他值(例如强度,颜色等)。 如果要获取有关其他CIFilters信息,则可以查看“ 核心图像过滤器参考”页面。

在本节的最后一行,我们最终设置了我们先前创建的按钮的背景图像。

// Assign filtered image to the button
        filterButton.setBackgroundImage(imageForButton, forState: .Normal)

将按钮添加到ScrollView

只需几行即可完成我们的viewDidLoad()方法:

// Add Buttons in the Scroll View
        xCoord +=  buttonWidth + gapBetweenButtons
        filtersScrollView.addSubview(filterButton)
    } // END FOR LOOP 
        
        
    // Resize Scroll View
    filtersScrollView.contentSize = CGSizeMake(buttonWidth * CGFloat(itemCount+2), yCoord)

} // END viewDidload()

我们将基于按钮的位置以及它们之间应保持的宽度和间隔将按钮作为子视图添加到filtersScrollView 。 然后最后我们关闭for循环。

最后,我们必须设置ScrollViewcontentSize以适合所有按钮。 在这里,我们最终使用先前声明的itemCount变量,将其转换为CGFloat (因为CGSizeMake它不接受Int值)。

筛选器按钮动作

仅需几行代码,我们就快完成了!

ViewController类的viewDidLoad()外部,创建filterButtonTapper()函数。 每次您点击我们之前生成的按钮之一时,就会调用此方法。

func filterButtonTapped(sender: UIButton) {
    let button = sender as UIButton
        
    imageToFilter.image = button.backgroundImageForState(UIControlState.Normal)
}

我们需要首先创建UIButton的实例,然后基于该按钮的背景图像设置imageToFilter的图像,该图像已经被放置在viewDidLoad()的代码过滤了。

确保名为imageToFilterUIImageView覆盖originalImage ,如下所示,否则该应用程序将不会向您显示已处理的图像,因为原始图像会将其隐藏。

imageToFilter必须在originalImage前面

保存处理后的图片

我们已经到了本教程的结尾,并且在.swift文件中仅添加了一个功能。 那是我们先前放在情节提要中的“保存”按钮。 按住Control和鼠标按钮,将UIButton的蓝线拖到班级中的空白处,释放鼠标按钮,将显示一个新的弹出窗口。 在这里,您必须将“ 连接”类型更改为“动作”,并输入方法的名称(在本例中为savePicButton ,然后单击“ 连接”按钮。

为“保存”按钮声明IBAction

这次您已经创建了一个IBAction这是必须放置在其中的代码:

// Save the image into camera roll
    UIImageWriteToSavedPhotosAlbum(imageToFilter.image!, nil, nil, nil)
        
    let alert = UIAlertView(title: "Filters",
                message: "Your image has been saved to Photo Library",
                delegate: nil,
                cancelButtonTitle: "OK")
    alert.show()

第一行只是将包含在imageToFilter的图像直接保存在设备或iOS Simulator的照片库中。 然后,我们触发一个简单的UIAlertView ,以确认该操作已完成。

好的,让我们运行我们的应用程序,看看如果点击底部的按钮会发生什么。 如果您正确完成了所有操作,则您的应用应如下所示:

应用显示了应用了滤色镜的图像


应用显示了应用了滤色镜的图像


应用显示消息已将图像保存到照片库的消息

翻译自: https://code.tutsplus.com/tutorials/ios-sdk-apply-photo-filters-with-core-image-in-swift--cms-27142

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值