Instagram와 같은 이미지 필터 라이브러리를 CocoaPods에서 공개했습니다.

이 기사는 Github에서 공개중인 이미지 필터 라이브러리 Sharaku의 내용과 만드는 방법을 설명한 기사입니다. 기사 내용으로는
  • CocoaPods를 사용하여 라이브러리를 만드는 방법
  • Core Image CIFilter 사용

  • 등이 주로 되어 있습니다.
    손쉽게 이미지 필터 기능을 사용하고 싶은 분은 pod 'Sharaku'를 podfile에 추가하여 사용해보십시오.
    라이브러리의 Github는 이쪽.
    htps : // 기주 b. 코 m / 마코모리 / 샤라쿠

    완성형





    만드는 방법



    CocoaPods로 프로젝트 만들기


    pod lib create Sharaku
    

    위의 명령을 실행하면 라이브러리 템플릿이 만들어집니다. 여러가지 듣기 때문에 적절히 대답해 봅시다. 「demo application 포함」에 Yes라고 대답하면 Example for Sharaku라는 디렉토리가 만들어지기 때문에 거기에 샘플 앱을 써 가고, Pods 안에 들어 있는 Development Pods로 실제의 라이브러리를 개발합니다.

    이미지 필터 기능 만들기



    중요한 UIImage의 필터 기능에 관해서는 Core Image의 CIFilter라는 클래스를 사용합니다. 이 클래스를 사용하면 Instagram 같은 필터를 몇 줄로 만들 수 있습니다.
    Sharaku에서는 다음과 같은 방법을 만들어 이미지를 필터링합니다.
    
    func createFilteredImage(filterName: String, image: UIImage) -> UIImage {
            // 1 - create source image
            let sourceImage = CIImage(image: image)
    
            // 2 - create filter using name
            let filter = CIFilter(name: filterName)
            filter?.setDefaults()
    
            // 3 - set source image
            filter?.setValue(sourceImage, forKey: kCIInputImageKey)
    
            // 4 - output filtered image as cgImage with dimension.
            let outputCGImage = context.createCGImage((filter?.outputImage!)!, from: (filter?.outputImage!.extent)!)
    
            // 5 - convert filtered CGImage to UIImage
            let filteredImage = UIImage(cgImage: outputCGImage!)
    
            return filteredImage
        }
    

    Sharaku에서 사용하는 필터 목록은 다음과 같습니다.
    
    "CIPhotoEffectChrome",
    "CIPhotoEffectFade",
    "CIPhotoEffectInstant",
    "CIPhotoEffectMono",
    "CIPhotoEffectNoir",
    "CIPhotoEffectProcess",
    "CIPhotoEffectTonal",
    "CIPhotoEffectTransfer",
    "CILinearToSRGBToneCurve",
    "CISRGBToneCurveToLinear"
    

    UIImageView에 UIGestureRecognizer를 올려 왼쪽과 오른쪽 스 와이프 제스처를 얻습니다.


    
    @IBAction func imageViewDidSwipeLeft() {
        if filterIndex == filterNameList.count - 1 {
            filterIndex = 0
            imageView?.image = image
        } else {
            filterIndex += 1
        }
        if filterIndex != 0 {
            applyFilter()
        }
        updateCellFont()
        scrollCollectionViewToIndex(itemIndex: filterIndex)
    }
    

    메인 ImageView에 적용된 필터와 아래의 CollectionView를 연동


    
    extension  SHViewController: UICollectionViewDataSource, UICollectionViewDelegate
    {
        public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! SHCollectionViewCell
            var filteredImage = smallImage
            if indexPath.row != 0 {
                filteredImage = createFilteredImage(filterName: filterNameList[indexPath.row], image: smallImage!)
            }
    
            cell.imageView.image = filteredImage
            cell.filterNameLabel.text = filterDisplayNameList[indexPath.row]
            updateCellFont()
            return cell
        }
    
        public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return filterNameList.count
        }
    
        public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
            filterIndex = indexPath.row
            if filterIndex != 0 {
                applyFilter()
            } else {
                imageView?.image = image
            }
            updateCellFont()
            scrollCollectionViewToIndex(itemIndex: indexPath.item)
        }
    }
    

    선택한 필터에 따라 레이블의 font-size 변경


    func updateCellFont() {
        // update font of selected cell
        if let selectedCell = collectionView?.cellForItem(at: IndexPath(row: filterIndex, section: 0)) {
            let cell = selectedCell as! SHCollectionViewCell
            cell.filterNameLabel.font = UIFont.boldSystemFont(ofSize: 14)
        }
    
        for i in 0...filterNameList.count - 1 {
            if i != filterIndex {
                // update nonselected cell font
                if let unselectedCell = collectionView?.cellForItem(at: IndexPath(row: i, section: 0)) {
                    let cell = unselectedCell as! SHCollectionViewCell
                    if #available(iOS 8.2, *) {
                        cell.filterNameLabel.font = UIFont.systemFont(ofSize: 14.0, weight: UIFontWeightThin)
                    } else {
                        // Fallback on earlier versions
                        cell.filterNameLabel.font = UIFont.systemFont(ofSize: 14.0)
                    }
                }
            }
        }
    }
    

    선택한 필터 변경에 따라 CollectionView 이동


    func scrollCollectionViewToIndex(itemIndex: Int) {
        let indexPath = IndexPath(item: itemIndex, section: 0)
        self.collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
    }
    

    주요 프로그램은 이상입니다. CIFilter를 알 때까지는 뭔가 어려울 것 같았던 이미지 필터도 실제로 만들어 보면 순식간이었습니다.

    라이브러리를 홍보하는 방법



  • Cocoacontrols에 게시합니다. (이것이 가장 효과적이었습니다.)
  • Github의 트렌드에 실린다. (Cocoacontrols 등으로부터의 유입으로 하루 50star 정도 붙이면 상위에 올라 오므로 star가 붙기 쉽습니다.)
  • awesome-ios와 같은 리포지토리에 올려 놓습니다.

  • 도서관을 홍보하는 다른 좋은 방법을 알고 계시다면 꼭 알려주세요.

    여담



    덧붙여서 이 라이브러리는 인스타그램 라이크한 카메라 기능을 제공해 주는 라이브러리 밀기울 에 인스파이어 되어 만들었습니다. 「심플하고, 깨끗한 필터를 도입하고 싶다.」 그런 요구에 응하는 소규모의 UI 라이브러리가 되고 있습니다.

    소스 코드가 좋지 않은, 이런 기능을 갖고 싶다, 등 뭔가 의견이 있으시면 Qiita 혹은 Github 어느 쪽이든 상관 없으니 꼭 지적해 주세요!

    좋은 웹페이지 즐겨찾기