日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

详解OS X和iOS图像处理框架Core Image

發布時間:2025/3/21 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详解OS X和iOS图像处理框架Core Image 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


詳解OS X和iOS圖像處理框架Core Image


width="22" height="16" src="http://hits.sinajs.cn/A1/weiboshare.html?url=http%3A%2F%2Fwww.csdn.net%2Farticle%2F2015-02-13%2F2823961-core-image&type=3&count=&appkey=&title=%E6%9C%AC%E6%96%87%E7%BB%93%E5%90%88%E5%AE%9E%E4%BE%8B%E8%AF%A6%E8%A7%A3%E4%BA%86OS%20X%E5%92%8CiOS%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%E6%A1%86%E6%9E%B6Core%20Image%E7%9A%84%E4%BD%BF%E7%94%A8%EF%BC%8C%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87Core%20Image%E6%9D%A5%E5%88%9B%E5%BB%BA%E5%92%8C%E4%BD%BF%E7%94%A8iOS%E7%9A%84%E5%86%85%E7%BD%AE%E6%BB%A4%E9%95%9C%EF%BC%8C%E9%9D%9E%E5%B8%B8%E9%80%82%E5%90%88%E5%88%9D%E5%AD%A6%E8%80%85%E5%AD%A6%E4%B9%A0%E3%80%82%E8%99%BD%E7%84%B6%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81%E6%98%AF%E7%94%A8Swift%E5%86%99%E7%9A%84iOS%E7%A8%8B%E5%BA%8F%EF%BC%8C%E4%B8%8D%E8%BF%87%E5%AE%9E%E7%8E%B0%E6%A6%82%E5%BF%B5%E5%BE%88%E5%AE%B9%E6%98%93%E8%BD%AC%E6%8D%A2%E5%88%B0Objective-C%E5%92%8COS%20X%E3%80%82&pic=&ralateUid=&language=zh_cn&rnd=1424043537328" frameborder="0" scrolling="no" allowtransparency="true">摘要:本文結合實例詳解了OS X和iOS圖像處理框架Core Image的使用,如何通過Core Image來創建和使用iOS的內置濾鏡,非常適合初學者學習。雖然示例代碼是用Swift寫的iOS程序,不過實現概念很容易轉換到Objective-C和OS X。

這篇文章會為初學者介紹一下Core Image,一個OS X和iOS的圖像處理框架。

如果你想跟著本文中的代碼學習,你可以在GitHub上下載示例工程。示例工程是一個iOS應用程序,列出了系統提供的大量圖像濾鏡以供選擇,并提供了一個用戶界面用來調整參數并觀察效果。

雖然示例代碼是用Swift寫的iOS程序,不過實現概念很容易轉換到Objective-C和OS X。

基本概念

說到Core Image,我們首先需要介紹幾個基本的概念。

一個濾鏡是一個對象,有很多輸入和輸出,并執行一些變換。例如,模糊濾鏡可能需要輸入圖像和一個模糊半徑來產生適當的模糊后的輸出圖像。

一個濾鏡圖表是一個鏈接在一起的濾鏡網絡(無回路有向圖),使得一個濾鏡的輸出可以是另一個濾鏡的輸入。以這種方式,可以實現精心制作的效果。我們將在下面看到如何連接濾鏡來創建一個復古的拍照效果。

熟悉Core Image API

有了上述的這些概念,我們可以開始探索Core Image的圖像濾鏡細節了。

Core Image架構

Core Image有一個插件架構,這意味著它允許用戶編寫自定義的濾鏡并與系統提供的濾鏡集成來擴展其功能。我們在這篇文章中不會用到Core Image的可擴展性;我提到它只是因為它影響到了框架的API。

Core Image 是用來最大化利用其所運行之上的硬件的。每個濾鏡實際上的實現,即內核,是由一個GLSL(即OpenGL的著色語言)的子集來書寫的。當多個濾鏡連接成一個濾鏡圖表,Core Image便把內核串在一起來構建一個可在GPU上運行的高效程序。

只要有可能,Core Image都會把工作延遲。通常情況下,直到濾鏡圖表的最后一個濾鏡的輸出被請求之前都不會發生分配或處理。

為了完成工作,Core Image需要一個稱為上下文(context)的對象。這個上下文是框架真正工作的地方,它需要分配必要的內存,并編譯和運行濾鏡內核來執行圖像處理。建立一個上下文是非常昂貴的,所以你會經常想創建一個反復使用的上下文。接下來我們將看到如何創建一個上下文。

查詢可用的濾鏡

Core Image濾鏡是按名字創建的。要獲得系統濾鏡的列表,我們要向Core Image的kCICategoryBuiltIn類別請求得到濾鏡的名字:

[cpp] view plaincopyprint?
  • let?filterNames?=?CIFilter.filterNamesInCategory(kCICategoryBuiltIn)?as?[String]??
  • let filterNames = CIFilter.filterNamesInCategory(kCICategoryBuiltIn) as [String]

    iOS上可用的濾鏡列表非常接近于OS X上可用濾鏡的一個子集。在OS X上有169個內置濾鏡,在iOS上有127個。

    通過名字創建一個濾鏡

    現在,我們有了可用濾鏡的列表,我們就可以創建和使用濾鏡了。例如,要創建一個高斯模糊濾鏡,我們傳給CIFilter初始化方法相應的名稱就可以了:

    [cpp] view plaincopyprint?
  • let?blurFilter?=?CIFilter(named:"CIGaussianBlur")???
  • let blurFilter = CIFilter(named:"CIGaussianBlur")

    設置濾鏡參數

    由于Core Image的插件結構,大多數濾鏡屬性并不是直接設置的,而是通過鍵值編碼(KVC)設置。例如,要設置模糊濾鏡的模糊半徑,我們使用KVC來設置inputRadius屬性:

    [cpp] view plaincopyprint?
  • blurFilter.setValue(10.0?forKey:"inputRadius")??
  • blurFilter.setValue(10.0 forKey:"inputRadius")

    由于這種方法需要AnyObject? (即Objective-C里的id)作為其參數值,它不是類型安全的。因此,設置濾鏡參數需要謹慎一些,確保你傳值的類型是正確的。

    查詢濾鏡屬性

    為了知道一個濾鏡提供什么樣的輸入和輸出參數,我們就可以分別獲取inputKeys和outputKeys數組。它們都返回NSString的數組。

    要獲取每個參數的詳細信息,我們可以看看由濾鏡提供的attributes字典。每個輸入和輸出參數名映射到它自己的字典里,描述了它是什么樣的參數,如果有的話還會給出它的最大值和最小值。例如,下面是 CIColorControls濾鏡對應的inputBrightness參數字典:

    [cpp] view plaincopyprint?
  • inputBrightness?=?{????
  • ????CIAttributeClass?=?NSNumber;??
  • ????CIAttributeDefault?=?0;??
  • ????CIAttributeIdentity?=?0;??
  • ????CIAttributeMin?=?-1;??
  • ????CIAttributeSliderMax?=?1;??
  • ????CIAttributeSliderMin?=?-1;??
  • ????CIAttributeType?=?CIAttributeTypeScalar;??
  • };??
  • inputBrightness = { CIAttributeClass = NSNumber;CIAttributeDefault = 0;CIAttributeIdentity = 0;CIAttributeMin = -1;CIAttributeSliderMax = 1;CIAttributeSliderMin = -1;CIAttributeType = CIAttributeTypeScalar; };

    對于數值參數,該字典會包含 kCIAttributeSliderMin 和 kCIAttributeSliderMax 鍵,來限制期望的輸入域。大多數參數還包含一個 kCIAttributeDefault 關鍵字,映射到該參數的默認值。

    圖片濾鏡實戰

    圖像濾鏡的工作由三部分組成:構建和配置濾鏡圖表,發送等待濾鏡處理的圖像,得到濾鏡處理后的圖像。下面的部分對此進行了詳細描述。

    構建一個濾鏡圖表

    構建一個濾鏡圖表由這幾個部分組成:實例化我們需要的濾鏡,設置它們的參數,把它們連接起來以便該圖像數據按順序傳過每個濾鏡。

    在本節中,我們將創建一個用來制作 19 世紀錫版照風格圖像的濾鏡圖表。我們將兩個效果鏈在一起來達到這種效果:同時去飽和以及染色調的黑白濾鏡,和一個暗角濾鏡來創建一個有陰影效果的加框圖片。

    用Quartz Composer,來做Core Image濾鏡圖表的原型非常有用,可以從蘋果開發者網站下載。下面,我們整理了所需的照片濾鏡,把黑白濾鏡和暗角濾鏡串在一起:


    一旦達到了我們滿意的效果,我們可以重新在代碼里創建濾鏡圖表:

    [cpp] view plaincopyprint?
  • let?sepiaColor?=?CIColor(red:?0.76,?green:?0.65,?blue:?0.54)????
  • let?monochromeFilter?=?CIFilter(name:?"CIColorMonochrome",????
  • ????withInputParameters:?["inputColor"?:?sepiaColor,?"inputIntensity"?:?1.0])??
  • monochromeFilter.setValue(inputImage,?forKey:?"inputImage")??
  • let?vignetteFilter?=?CIFilter(name:?"CIVignette",????
  • ????withInputParameters:?["inputRadius"?:?1.75,?"inputIntensity"?:?1.0])??
  • vignetteFilter.setValue(monochromeFilter.outputImage,?forKey:?"inputImage")??
  • let?outputImage?=?vignetteFilter.outputImage??
  • let sepiaColor = CIColor(red: 0.76, green: 0.65, blue: 0.54) let monochromeFilter = CIFilter(name: "CIColorMonochrome", withInputParameters: ["inputColor" : sepiaColor, "inputIntensity" : 1.0]) monochromeFilter.setValue(inputImage, forKey: "inputImage") let vignetteFilter = CIFilter(name: "CIVignette", withInputParameters: ["inputRadius" : 1.75, "inputIntensity" : 1.0]) vignetteFilter.setValue(monochromeFilter.outputImage, forKey: "inputImage") let outputImage = vignetteFilter.outputImage

    需要注意的是黑白濾鏡的輸出圖像變為暗角濾鏡的輸入圖像。這將導致暗角效果要應用到黑白圖像上。還要注意的是,我們可以在初始化中指定參數,而不一定需要用KVC單獨設置它們。

    創建輸入圖像

    Core Image濾鏡要求其輸入圖像是CIImage類型。而對于iOS的程序員來說這可能會有一點不尋常,因為他們更習慣用UIImage,但這個區別是值得的。一個CIImage實例實際上比UIImage更全面,因為CIImage可以無限大。當然,我們不能存儲無限的圖像在內存中,但在概念上,這意味著你可以從2D平面上的任意區域獲取圖像數據,并得到一個有意義的結果。

    所有我們在本文中使用的圖像都是有限的,而且也可以很容易從一個UIImage來創建一個CIImage。事實上,這只需要一行代碼:

    [cpp] view plaincopyprint?
  • let?inputImage?=?CIImage(image:?uiImage)??
  • let inputImage = CIImage(image: uiImage)

    也有很方便的初始化方法直接從圖像數據或文件URL來創建CIImage。

    一旦我們有了一個CIImage,我們就可以通過設置濾鏡的inputImage參數來將其設置為濾鏡的輸入圖像:

    [cpp] view plaincopyprint?
  • filter.setValue(inputImage,?forKey:"inputImage")??
  • filter.setValue(inputImage, forKey:"inputImage")

    得到一個濾鏡處理后的圖片

    濾鏡都有一個名為outputImage的屬性。正如你可能已經猜到的一樣,它是 CIImage 類型的。那么,我們如何實現從一個CIImage創建UIImage這樣一個反向操作?好了,雖然我們到此已經花了所有的時間建立一個濾鏡圖表,現在是調用CIContext的力量來實際的做圖像濾鏡處理工作的時候了。

    創建一個上下文最簡單的方法是給它的構造方法傳一個nil字典:

    [cpp] view plaincopyprint?
  • let?ciContext?=?CIContext(options:?nil)??
  • let ciContext = CIContext(options: nil)

    為了得到一個濾鏡處理過的圖像,我們需要CIContext從輸出圖像的一個矩形內創建一個CGImage,傳入輸入圖像的范圍(bounds):

    [cpp] view plaincopyprint?
  • let?cgImage?=?ciContext.createCGImage(filter.outputImage,?fromRect:?inputImage.extent())??
  • let cgImage = ciContext.createCGImage(filter.outputImage, fromRect: inputImage.extent())

    我們使用輸入圖像大小的原因是,輸出圖像通常和輸入圖像具有不同的尺寸比。例如,一個模糊圖像由于采樣超出了輸入圖像的邊緣,圍繞在其邊界外還會有一些額外的像素。

    現在,我們可以從這個新創建的CGImage來創建一個UIImage了:

    [cpp] view plaincopyprint?
  • let?uiImage?=?UIImage(CGImage:?cgImage)??
  • let uiImage = UIImage(CGImage: cgImage)

    直接從一個CIImage創建UIImage也是可以的,但這種方法有點讓人郁悶:如果你試圖在一個UIImageView上顯示這樣的圖像,其contentMode屬性將被忽略。使用過渡的CGImage則需要一個額外的步驟,但可以省去這一煩惱。

    用OpenGL來提高性能

    用CPU來繪制一個CGImage是非常耗時和浪費的,它只將結果回傳給UIKit來做合成。我們更希望能夠在屏幕上繪制應用濾鏡后的圖像,而不必去Core Graphics里繞一圈。幸運的是,由于OpenGL和Core Image的可互操作性,我們可以這么做。

    要OpenGL上下文和Core Image上下文之間共享資源,我們需要用一個稍微不同的方式來創建我們的 CIContext:

    [cpp] view plaincopyprint?
  • let?eaglContext?=?EAGLContext(API:?.OpenGLES2)????
  • let?ciContext?=?CIContext(EAGLContext:?context)??
  • let eaglContext = EAGLContext(API: .OpenGLES2) let ciContext = CIContext(EAGLContext: context)

    在這里,我們用OpenGL ES 2.0的功能集創建了一個EAGLContext。這個GL上下文可以用作一個GLKView的背襯上下文或用來繪制成一個CAEAGLLayer。示例代碼使用這種技術來有效地繪制圖像。

    當一個CIContext具有了關聯GL的上下文,濾鏡處理后的圖像就可用OpenGL來繪制,像如下這樣調用方法:

    [cpp] view plaincopyprint?
  • ciContext.drawImage(filter.outputImage,?inRect:?outputBounds,?fromRect:?inputBounds)??
  • ciContext.drawImage(filter.outputImage, inRect: outputBounds, fromRect: inputBounds)

    與以前一樣,fromRect 參數是用濾鏡處理后的圖像的坐標空間來繪制的圖像的一部分。這個inRect 參數是GL上下文的坐標空間的矩形應用到需要繪制圖像上。如果你想保持圖像的長寬比,你可能需要做一些數學計算來得到適當的inRect。

    強制在CPU上做濾鏡操作

    只要有可能,Core Image將在GPU上執行濾鏡操作。然而,它確實有回滾到CPU上執行的可能。濾鏡操作在CPU上完成可具有更好的精確度,因為GPU經常在浮點計算上以失真換得更快的速度。在創建一個上下文時,你可以通過設置kCIContextUseSoftwareRenderer關鍵字的值為true來強制Core Image在CPU上運行。

    你可以通過在Xcode中設置計劃配置(scheme configuration)里的CI_PRINT_TREE環境變量為1來決定用CPU ?還是GPU來渲染。這將導致每次一個濾鏡處理圖像被渲染的時候Core Image都會打印診斷信息。此設置用來檢查合成圖像濾鏡樹也很有用。

    示例應用一覽

    本文的示例代碼是一個iPhone應用程序,展示了iOS里大量的各式Core Image圖像濾鏡。

    為濾鏡參數創建一個GUI

    為了盡可能多的演示各種濾鏡,示例應用程序利用了Core Image的內省特點生成了一個界面,用于控制它支持的濾鏡參數:


    示例應用程序只限于單一的圖像輸入以及零個或多個數值輸入的濾鏡。也有一些有趣的濾鏡不屬于這一類(特別是那些合成和轉換濾鏡)。即便如此,該應用程序仍然很好的概述了Core Image支持的功能。

    對于每個濾鏡的輸入參數,都有一個滑動條可以用于配置參數的最小值和最大值,其值被設置為默認值。當滑動條的值發生變化時,它把改變后的值傳給它的 delegate,一個持有CIFilter引用的 UIImageView子類。

    使用內建的照片濾鏡

    除了許多其他的內置濾鏡,示例應用程序還展示了iOS 7中引入的照片濾鏡。這些濾鏡沒有我們可以調整的參數,但它們值得被囊括進來,因為它們展示了如何在iOS中模擬照片應用程序的效果:


    結論

    這篇文章簡要介紹了Core Image這個高性能的圖像處理框架。我們一直在試圖在如此簡短的形式內盡可能多的展示這個框架的功能。你現在已經學會了如何實例化和串聯Core Image的濾鏡,在濾鏡圖表傳入和輸出圖像,以及調整參數來獲得想要的結果。你還學習了如何訪問系統提供的照片濾鏡,用以模擬在iOS上的照片應用程序的行為。

    現在你知道了足夠多的東西來寫你自己的照片編輯應用程序了。隨著更多的一些探索,你就可以寫自己的濾鏡了,利用你的Mac或iPhone的神奇的力量來執行以前無法想象的效果。快去動手做吧!

    參考

    • Core Image Reference Collection是Core Image的權威文檔集。
    • Core Image Filter Reference包含了Core Image提供的圖像濾鏡的完整列表,以及用法示例。
    • 如果想要寫更函數式風格的Core Image代碼,可以看看Florian Kluger在objccn.io話題#16里的文章。

    總結

    以上是生活随笔為你收集整理的详解OS X和iOS图像处理框架Core Image的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美一区二区三区四区在线 | 免费观看成人在线视频 | 中文字幕乱码中文乱码b站 国产一区二区三区在线观看视频 | 亚洲涩视频 | h无码动漫在线观看 | 国产传媒av在线 | 日韩一区二区三区不卡视频 | 美女被到爽高潮视频 | 日韩av影片在线观看 | 在线一级视频 | 毛片网站免费观看 | 亚洲一区影视 | 伊人成人动漫 | 久久久欧洲 | 第一福利在线视频 | 亚洲国产精品成人无码区 | 日韩av电影网 | 国产精品探花视频 | 瑟瑟网站在线观看 | 少妇又色又爽又黄的视频 | 公侵犯一区二区三区四区中文字幕 | 91精品国产99久久久久久 | 高清视频在线播放 | 台湾三级伦理片 | 神马午夜久久 | 亚洲av无码国产精品麻豆天美 | 美女网站免费 | av成人在线免费观看 | 成人91免费视频 | 国产精品蜜 | 日本性爱视频在线观看 | 丁香婷婷六月天 | 成人播放器 | 免费三片在线播放 | 天天干夜夜怕 | 99久久久国产精品无码网爆 | 美女被啪啪 | 久久国产中文 | 琪琪午夜伦理影院7777 | av噜噜色 | 亚洲av无码乱码国产精品 | 日韩亚洲视频在线观看 | 无码内射中文字幕岛国片 | 黄色av网站在线免费观看 | 后入内射无码人妻一区 | 91综合在线 | 亚洲综合五月 | 波多野结衣网址 | mm131丰满少妇人体欣赏图 | 香蕉色网 | 久久久成 | 你懂的视频在线播放 | 日韩经典在线观看 | 91爱爱爱爱 | 日韩电影一区二区三区 | 婷婷综合在线视频 | 超碰2023 | 日韩精品视频在线看 | 日本久久综合 | 亚洲va中文字幕 | www.爆操 | 日韩视频a| 日本午夜精品 | 国产一卡二卡三卡四卡 | av高清不卡 | 无码人妻精品一区二区三区不卡 | 亚洲成人av一区二区 | 日韩精品一区二区电影 | 久草精品在线观看视频 | 亚洲综合a | 亚洲午夜一区二区 | 中文字幕免费观看视频 | 91污网站 | 在线碰| 免费成人在线观看视频 | 欧美亚洲精品在线 | 精品视频一区二区在线 | 爽爽爽av| 两个人看的www视频免费完整版 | 成年女人18级毛片毛片免费 | 亚洲人网 | 一区二区三区四区久久 | 午夜小视频免费 | 亚洲精品国产精品乱码桃花 | 每日在线更新av | 成人激情免费视频 | 91色站 | 厕拍极品| 亚洲伊人成人网 | 日本吃奶摸下激烈网站动漫 | 综合激情亚洲 | 日韩免费av| 完全免费av| 成人黄色激情网 | 成人av网址在线观看 | 中文在线资源 | 丁香婷婷激情 | 麻豆91视频 | 美女光屁屁露胸胸 |