স্ট্রিংয়ে চরিত্রটি ইমোজি কিনা তা সন্ধান করুন?


90

স্ট্রিংয়ের একটি চরিত্র ইমোজি কিনা তা আমার খুঁজে বের করতে হবে।

উদাহরণস্বরূপ, আমার এই চরিত্রটি রয়েছে:

let string = "😀"
let character = Array(string)[0]

সেই চরিত্রটি ইমোজি কিনা তা আমাকে খুঁজে বের করতে হবে।


আমি কৌতূহলী: আপনার কেন এই তথ্য দরকার?
মার্টিন আর

@ এরিকডি: অনেকগুলি ইউনিকোড অক্ষর রয়েছে যা একাধিক ইউটিএফ -8 কোড পয়েন্ট নেয় (যেমন "€" = E2 82 এসি) বা একাধিক ইউটিএফ -16 কোড পয়েন্ট (যেমন "𝄞" = D834 DD1E)।
মার্টিন আর

আশা করি আপনি কোড এই obj-C সংস্করণ থেকে একটি ধারণা পেয়েছেন হবে stackoverflow.com/questions/19886642/...
আশিস Kakkad

স্ট্রিংগুলির সূচি থাকে যা সেগুলি ব্যবহারের পছন্দসই উপায়। একটি নির্দিষ্ট চরিত্র পেতে (বা বরং গ্রাফিয়াম ক্লাস্টার) পেতে পারেন: let character = string[string.index(after: string.startIndex)]বা let secondCharacter = string[string.index(string.startIndex, offsetBy: 1)]
পল বি

উত্তর:


229

আমি যা হোঁচট খেয়েছি তা হ'ল অক্ষর, ইউনিকোড স্কেলার এবং গ্লাইফের মধ্যে পার্থক্য।

উদাহরণস্বরূপ, গ্লাইফ ‍👨‍👧‍👧 7 টি ইউনিকোড স্কেলার নিয়ে গঠিত:

  • চারটি ইমোজি অক্ষর: 👨👩👧👧
  • প্রতিটি ইমোজি এর মধ্যে একটি বিশেষ চরিত্র থাকে যা চরিত্রের আঠার মতো কাজ করে; দেখতে আরও তথ্যের জন্য চশমা

অন্য উদাহরণ, গ্লাইফ 2 টি ইউনিকোড স্কেলার নিয়ে গঠিত:

  • নিয়মিত ইমোজি: 👌
  • একটি ত্বকের স্বন সংশোধক: 🏿

শেষটি, গ্লিফ 1️⃣ এ তিনটি ইউনিকোড অক্ষর রয়েছে:

সুতরাং চরিত্রগুলি রেন্ডার করার সময়, ফলস্বরূপ গ্লাইফগুলি সত্যই গুরুত্বপূর্ণ।

উপরের সুইচ 5.0 এবং এই প্রক্রিয়াটি আরও সহজ করে তোলে এবং আমাদের করা অনুমান করা কিছু থেকে মুক্তি পেয়ে যায়। Unicode.ScalarনতুনProperty ধরণের সাহায্যে আমরা কী কাজ করছি তা নির্ধারণ করতে সহায়তা করে। যাইহোক, গ্লিফের মধ্যে অন্যান্য স্কেলারগুলি পরীক্ষা করার সময় এই বৈশিষ্ট্যগুলি কেবল তখনই বোধগম্য হয়। এ কারণেই আমরা আমাদের সাহায্য করতে অক্ষর শ্রেণিতে কিছু সুবিধা পদ্ধতি যুক্ত করব।

আরও বিশদ জন্য, আমি এই নিবন্ধটি লিখে কিভাবে এটি কাজ করে

সুইফ্ট 5.0 এর জন্য এটি আপনাকে নিম্নলিখিত ফলাফল সহ ছেড়ে দেয়:

extension Character {
    /// A simple emoji is one scalar and presented to the user as an Emoji
    var isSimpleEmoji: Bool {
        guard let firstScalar = unicodeScalars.first else { return false }
        return firstScalar.properties.isEmoji && firstScalar.value > 0x238C
    }

    /// Checks if the scalars will be merged into an emoji
    var isCombinedIntoEmoji: Bool { unicodeScalars.count > 1 && unicodeScalars.first?.properties.isEmoji ?? false }

    var isEmoji: Bool { isSimpleEmoji || isCombinedIntoEmoji }
}

extension String {
    var isSingleEmoji: Bool { count == 1 && containsEmoji }

    var containsEmoji: Bool { contains { $0.isEmoji } }

    var containsOnlyEmoji: Bool { !isEmpty && !contains { !$0.isEmoji } }

    var emojiString: String { emojis.map { String($0) }.reduce("", +) }

    var emojis: [Character] { filter { $0.isEmoji } }

    var emojiScalars: [UnicodeScalar] { filter { $0.isEmoji }.flatMap { $0.unicodeScalars } }
}

যা আপনাকে নিম্নলিখিত ফলাফলগুলি দেবে:

"A̛͚̖".containsEmoji // false
"3".containsEmoji // false
"A̛͚̖▶️".unicodeScalars // [65, 795, 858, 790, 9654, 65039]
"A̛͚̖▶️".emojiScalars // [9654, 65039]
"3️⃣".isSingleEmoji // true
"3️⃣".emojiScalars // [51, 65039, 8419]
"👌🏿".isSingleEmoji // true
"🙎🏼‍♂️".isSingleEmoji // true
"🇹🇩".isSingleEmoji // true
"⏰".isSingleEmoji // true
"🌶".isSingleEmoji // true
"👨‍👩‍👧‍👧".isSingleEmoji // true
"🏴󠁧󠁢󠁳󠁣󠁴󠁿".isSingleEmoji // true
"🏴󠁧󠁢󠁥󠁮󠁧󠁿".containsOnlyEmoji // true
"👨‍👩‍👧‍👧".containsOnlyEmoji // true
"Hello 👨‍👩‍👧‍👧".containsOnlyEmoji // false
"Hello 👨‍👩‍👧‍👧".containsEmoji // true
"👫 Héllo 👨‍👩‍👧‍👧".emojiString // "👫👨‍👩‍👧‍👧"
"👨‍👩‍👧‍👧".count // 1

"👫 Héllœ 👨‍👩‍👧‍👧".emojiScalars // [128107, 128104, 8205, 128105, 8205, 128103, 8205, 128103]
"👫 Héllœ 👨‍👩‍👧‍👧".emojis // ["👫", "👨‍👩‍👧‍👧"]
"👫 Héllœ 👨‍👩‍👧‍👧".emojis.count // 2

"👫👨‍👩‍👧‍👧👨‍👨‍👦".isSingleEmoji // false
"👫👨‍👩‍👧‍👧👨‍👨‍👦".containsOnlyEmoji // true

পুরানো সুইফ্ট সংস্করণগুলির জন্য, আমার পুরাতন কোডযুক্ত এই গিস্টটি দেখুন।


6
এটি এখানকার সেরা এবং সবচেয়ে সঠিক উত্তর। ধন্যবাদ! একটি ছোট টীকা, আপনার উদাহরণগুলি কোডটির সাথে মেলে না (আপনি স্নিপকেটে ইমোজি ধারণ করে কেবলমাত্র ইমোকির নাম পরিবর্তন করেছেন - আমি অনুমান করি যে এটি আরও সঠিক, আমার পরীক্ষায় এটি মিশ্র অক্ষরের সাথে স্ট্রিংয়ের ক্ষেত্রে সত্য ফিরে এসেছিল)।
টিম বুল

4
আমার খারাপ, আমি কিছু কোডের আশেপাশে পরিবর্তিত হয়েছি, অনুমান করি আমি গোলযোগ পেয়েছি। আমি উদাহরণটি আপডেট করেছি
কেভিন আর

4
@ অ্যান্ড্রু: অবশ্যই, আমি এটি দেখানোর জন্য উদাহরণটিতে আরও একটি পদ্ধতি যুক্ত করেছি।
কেভিন আর

4
@ এন্ড্রু যেখানে এটি সত্যিই অগোছালো হয়। কীভাবে এটি করা যায় আমি একটি উদাহরণ যুক্ত করেছি। সমস্যাটি হ'ল আমি বুঝতে পেরেছি যে কোর টেক্সট কীভাবে কেবল অক্ষরগুলি পরীক্ষা করে গ্লিফগুলি রেন্ডার করে। ক্লিনার পদ্ধতির জন্য কারও কাছে যদি পরামর্শ থাকে তবে দয়া করে আমাকে জানান।
কেভিন আর

4
@ অ্যান্ড্রু এটি নির্দেশ করার জন্য ধন্যবাদ, আমি containsOnlyEmojiচেকের উপায়টি পরিবর্তন করেছি । আমি উদাহরণটি সুইফট 3.0 এও আপডেট করেছি।
কেভিন আর

48

এটি সম্পাদন করার সহজতম, সবচেয়ে সহজ এবং দ্রুততম উপায় হ'ল পরিচিত ইমোজি এবং ডিংব্যাটস রেঞ্জের বিপরীতে স্ট্রিংয়ের প্রতিটি অক্ষরের জন্য ইউনিকোড কোড পয়েন্টগুলি পরীক্ষা করা সহজ:

extension String {

    var containsEmoji: Bool {
        for scalar in unicodeScalars {
            switch scalar.value {
            case 0x1F600...0x1F64F, // Emoticons
                 0x1F300...0x1F5FF, // Misc Symbols and Pictographs
                 0x1F680...0x1F6FF, // Transport and Map
                 0x2600...0x26FF,   // Misc symbols
                 0x2700...0x27BF,   // Dingbats
                 0xFE00...0xFE0F,   // Variation Selectors
                 0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs
                 0x1F1E6...0x1F1FF: // Flags
                return true
            default:
                continue
            }
        }
        return false
    }

}

9
এর মতো একটি কোড উদাহরণ কোনও তৃতীয় পক্ষের লাইব্রেরি নির্ভরতা অন্তর্ভুক্ত করার পরামর্শ দেওয়ার চেয়ে ভাল। শারদুলের উত্তর মেনে চলার মতো বুদ্ধিমান পরামর্শ — সর্বদা আপনার নিজের কোড লিখুন।
thefaj

এটি দুর্দান্ত, কেসের সাথে সম্পর্কিত তা মন্তব্য করার জন্য আপনাকে ধন্যবাদ
শন থ্রুপ

4
আপনার কোডটি অনেক পছন্দ করে, আমি এখানে একটি উত্তরে এটি প্রয়োগ করেছি । একটি জিনিস আমি লক্ষ্য করেছি যে এটি কিছু ইমোজি মিস করে, কারণ তারা আপনার তালিকাভুক্ত বিভাগের অংশ না হওয়ায় সম্ভবত এটির একটি: রোবট ফেস ইমোজি 🤖
কিউ

4
@ টেল আমি অনুমান করি এটির পরিসীমা 0x1F900...0x1F9FF(উইকিপিডিয়া প্রতি) হবে। নিশ্চিত নয় যে সমস্ত পরিসীমা ইমোজি হিসাবে বিবেচনা করা উচিত।
ফ্রিজ্লাব

8
extension String {
    func containsEmoji() -> Bool {
        for scalar in unicodeScalars {
            switch scalar.value {
            case 0x3030, 0x00AE, 0x00A9,// Special Characters
            0x1D000...0x1F77F,          // Emoticons
            0x2100...0x27BF,            // Misc symbols and Dingbats
            0xFE00...0xFE0F,            // Variation Selectors
            0x1F900...0x1F9FF:          // Supplemental Symbols and Pictographs
                return true
            default:
                continue
            }
        }
        return false
    }
}

এটি আপডেট করা রেঞ্জগুলির সাথে আমার ফিক্স।


8

সুইফ্ট 5.0

… ঠিক এই চেক করার একটি নতুন উপায় চালু!

আপনাকে Stringএটির মধ্যে ভাঙ্গতে হবে Scalars। প্রত্যেকের Scalarএকটি Propertyমান রয়েছে যা সমর্থন করেisEmoji !

আসলে আপনি এমনকি স্কেলারটি ইমোজি সংশোধক বা আরও বেশি কিনা তাও পরীক্ষা করতে পারেন। অ্যাপলের ডকুমেন্টেশন দেখুন: https://developer.apple.com/docamentation/swift/unicode/scalar/properties

আপনি পরীক্ষা করার কথা বিবেচনা করতে পারেন isEmojiPresentationপরিবর্তে isEmoji, কারণ অ্যাপল জন্য নিম্নলিখিত যুক্তরাষ্ট্রের isEmoji:

এই সম্পত্তিটি স্কেলারের ক্ষেত্রে সত্য যা ডিফল্টরূপে ইমোজি হিসাবে রেন্ডার করা হয় এবং স্কেলারের ক্ষেত্রেও যখন ইউ + FE0F ভেরিয়েশন নির্বাচন -16 অনুসরণ করে একটি অ-ডিফল্ট ইমোজি রেন্ডারিং থাকে। এর মধ্যে এমন কিছু স্কেলার রয়েছে যা সাধারণত ইমোজি হিসাবে বিবেচিত হয় না।


এই পদ্ধতিটি ইমোজিগুলিকে সমস্ত সংশোধকগুলিতে ভাগ করে দেয় তবে এটি পরিচালনা করা সহজ simp এবং সুইফট এখন ইমোজিদের সংশোধনকারী হিসাবে গণনা করেছে (যেমন: 👨‍👩‍👧‍👦, 👨🏻‍💻, 🏴) আপনি 1 হিসাবে সমস্ত ধরণের স্টাফ করতে পারেন।

var string = "🤓 test"

for scalar in string.unicodeScalars {
    let isEmoji = scalar.properties.isEmoji

    print("\(scalar.description) \(isEmoji)"))
}

// 🤓 true
//   false
// t false
// e false
// s false
// t false

NSHipster সমস্ত ইমোজি পাওয়ার একটি আকর্ষণীয় উপায় উল্লেখ করেছে:

import Foundation

var emoji = CharacterSet()

for codePoint in 0x0000...0x1F0000 {
    guard let scalarValue = Unicode.Scalar(codePoint) else {
        continue
    }

    // Implemented in Swift 5 (SE-0221)
    // https://github.com/apple/swift-evolution/blob/master/proposals/0221-character-properties.md
    if scalarValue.properties.isEmoji {
        emoji.insert(scalarValue)
    }
}

4
দুর্দান্ত উত্তর, ধন্যবাদ। এটি উল্লেখ করার মতো যে সুইফট 5 এর এই অংশটি ব্যবহার করার জন্য আপনার ন্যূনতম এসডিকে অবশ্যই 10.2 হওয়া উচিত Also এছাড়াও স্ট্রিংটি কেবল ইমোজিগুলি দিয়ে তৈরি হয়েছিল কিনা তা পরীক্ষা করার জন্য আমাকে এটির এই বৈশিষ্ট্যগুলির একটি ছিল কিনা তা পরীক্ষা করে দেখতে হবে:scalar.properties.isEmoji scalar.properties.isEmojiPresentation scalar.properties.isEmojiModifier scalar.properties.isEmojiModifierBase scalar.properties.isJoinControl scalar.properties.isVariationSelector
একটি স্প্রিংহাম

6
সাবধান, 0-9 পূর্ণসংখ্যাকে ইমোজি হিসাবে বিবেচনা করা হয়। সুতরাং "6".unicodeScalars.first!.properties.isEmojiমূল্যায়ন করা হবেtrue
মিনিরু

6

সুইফ্ট 5 এর সাহায্যে আপনি এখন আপনার স্ট্রিংয়ের প্রতিটি অক্ষরের ইউনিকোড বৈশিষ্ট্যগুলি পরীক্ষা করতে পারবেন। এটি আমাদের isEmojiপ্রতিটি অক্ষরে সুবিধাজনক পরিবর্তনশীল দেয় । সমস্যাটি এমন isEmojiকোনও চরিত্রের জন্য সত্য ফিরে আসবে যা 2-বাইট ইমোজি, যেমন 0-9 এ রূপান্তরিত হতে পারে for

isEmojiঅস্পষ্ট অক্ষরগুলি ইমোজি হিসাবে প্রদর্শিত হবে কিনা তা নির্ধারণ করতে আমরা ভেরিয়েবলটি দেখতে পারি এবং ইমোজি সংশোধকটির উপস্থিতিও পরীক্ষা করতে পারি।

এই প্রস্তাবটি এখানে প্রস্তাবিত রেজেক্স সমাধানগুলির চেয়ে অনেক বেশি ভবিষ্যতের প্রমাণ হওয়া উচিত।

extension String {
    func containsOnlyEmojis() -> Bool {
        if count == 0 {
            return false
        }
        for character in self {
            if !character.isEmoji {
                return false
            }
        }
        return true
    }
    
    func containsEmoji() -> Bool {
        for character in self {
            if character.isEmoji {
                return true
            }
        }
        return false
    }
}

extension Character {
    // An emoji can either be a 2 byte unicode character or a normal UTF8 character with an emoji modifier
    // appended as is the case with 3️⃣. 0x238C is the first instance of UTF16 emoji that requires no modifier.
    // `isEmoji` will evaluate to true for any character that can be turned into an emoji by adding a modifier
    // such as the digit "3". To avoid this we confirm that any character below 0x238C has an emoji modifier attached
    var isEmoji: Bool {
        guard let scalar = unicodeScalars.first else { return false }
        return scalar.properties.isEmoji && (scalar.value > 0x238C || unicodeScalars.count > 1)
    }
}

আমাদের দিচ্ছেন

"hey".containsEmoji() //false

"Hello World 😎".containsEmoji() //true
"Hello World 😎".containsOnlyEmojis() //false

"3".containsEmoji() //false
"3️⃣".containsEmoji() //true

4
এবং কি আরো হয় Character("3️⃣").isEmoji // trueযখনCharacter("3").isEmoji // false
পল বি

4

সুইফট 3 নোট:

এটি প্রদর্শিত হয় cnui_containsEmojiCharactersপদ্ধতিটি মুছে ফেলা হয়েছে বা একটি ভিন্ন গতিশীল লাইব্রেরিতে সরানো হয়েছে। _containsEmojiএখনও কাজ করা উচিত।

let str: NSString = "hello😊"

@objc protocol NSStringPrivate {
    func _containsEmoji() -> ObjCBool
}

let strPrivate = unsafeBitCast(str, to: NSStringPrivate.self)
strPrivate._containsEmoji() // true
str.value(forKey: "_containsEmoji") // 1


let swiftStr = "hello😊"
(swiftStr as AnyObject).value(forKey: "_containsEmoji") // 1

সুইফট 2.x:

আমি সম্প্রতি একটি প্রাইভেট এপিআই আবিষ্কার করেছি NSStringযার উপর স্ট্রিংয়ে ইমোজি অক্ষর রয়েছে কিনা তা সনাক্ত করার জন্য কার্যকারিতা প্রকাশ করে:

let str: NSString = "hello😊"

একটি অবজেক্ট প্রোটোকল এবং সহ unsafeBitCast:

@objc protocol NSStringPrivate {
    func cnui_containsEmojiCharacters() -> ObjCBool
    func _containsEmoji() -> ObjCBool
}

let strPrivate = unsafeBitCast(str, NSStringPrivate.self)
strPrivate.cnui_containsEmojiCharacters() // true
strPrivate._containsEmoji() // true

সাথে valueForKey:

str.valueForKey("cnui_containsEmojiCharacters") // 1
str.valueForKey("_containsEmoji") // 1

খাঁটি সুইফ্ট স্ট্রিং সহ, আপনার অবশ্যই স্ট্রিংটি AnyObjectব্যবহারের আগে যেমন কাস্ট করতে হবে valueForKey:

let str = "hello😊"

(str as AnyObject).valueForKey("cnui_containsEmojiCharacters") // 1
(str as AnyObject).valueForKey("_containsEmoji") // 1

এনএসএসস্ট্রিং শিরোলেখ ফাইলটিতে পদ্ধতিগুলি পাওয়া গেছে ।


এটি আমি যা খুঁজছি, ধন্যবাদ

এটি কি অ্যাপল প্রত্যাখ্যান করবে?
আন্দ্রে চেরুনুখা

@ অ্যান্ড্রে চেরুনুখা সর্বদা একটি ঝুঁকি থাকে, তবে আমি এখনও কোনও প্রত্যাখ্যান করতে পারি নি।
জাল

প্রাইভেট এপিআই কখনও ব্যবহার করবেন না। সর্বোপরি, আঘাতটি কেবল আগামীকালই আসবে। বা পরের মাসে।
xaphod

3

আপনি এই কোড উদাহরণ বা এই পড ব্যবহার করতে পারেন ।

সুইফটে এটি ব্যবহার করতে, বিভাগটিতে বিভাগটি আমদানি করুন YourProject_Bridging_Header

#import "NSString+EMOEmoji.h"

তারপরে আপনি আপনার স্ট্রিংয়ের প্রতিটি ইমোজি জন্য রেঞ্জটি পরীক্ষা করতে পারেন:

let example: NSString = "string👨‍👨‍👧‍👧with😍emojis✊🏿" //string with emojis

let containsEmoji: Bool = example.emo_containsEmoji()

    print(containsEmoji)

// Output: ["true"]

আমি উপরের কোড সহ একটি ছোট উদাহরণ প্রকল্প তৈরি করেছি।


3

ভবিষ্যতের প্রমাণ: ম্যানুয়ালি চরিত্রটির পিক্সেল পরীক্ষা করুন; নতুন ইমোজিগুলি যুক্ত হওয়ার সাথে সাথে অন্যান্য সমাধানগুলি ভেঙ্গে যাবে (এবং ভেঙে গেছে)।

দ্রষ্টব্য: এটি উদ্দেশ্যমূলক-সি (সুইফটে রূপান্তরিত হতে পারে)

বছরের পর বছর ধরে এই ইমোজি সনাক্তকরণের সমাধানগুলি ভাঙতে থাকে কারণ অ্যাপল নতুন ইমোজিস ডাব্লু / নতুন পদ্ধতি যুক্ত করে (যেমন স্কিন-টোনড ইমোজিগুলি একটি অতিরিক্ত চরিত্রের সাথে একটি অক্ষরের প্রাক-শাপ দিয়ে নির্মিত), ইত্যাদি etc.

আমি অবশেষে ভেঙেছি এবং কেবলমাত্র নিম্নলিখিত পদ্ধতিটি লিখেছি যা সমস্ত বর্তমান ইমোজিদের জন্য কাজ করে এবং ভবিষ্যতের সমস্ত ইমোজিদের জন্য কাজ করা উচিত।

সমাধান অক্ষর এবং একটি কালো পটভূমি সহ একটি ইউআইএলবেল তৈরি করে। সিজি এর পরে লেবেলের একটি স্ন্যাপশট নেয় এবং আমি কোনও সলিড-কালো পিক্সেলের জন্য স্ন্যাপশটে সমস্ত পিক্সেল স্ক্যান করি। আমি কালো পটভূমি যুক্ত করার কারণ হ'ল সাবপিক্সেল রেন্ডারিংয়ের কারণে মিথ্যা-বর্ণের সমস্যাগুলি এড়ানো

সমাধানটি আমার ডিভাইসে খুব দ্রুত সঞ্চালিত হয়, আমি কয়েক সেকেন্ডে কয়েক হাজার অক্ষর চেক করতে পারি, তবে এটি লক্ষ্য করা উচিত যে এটি একটি কোরগ্রাফিক্স সমাধান এবং আপনার নিয়মিত পাঠ্য পদ্ধতির মতো ভারী ব্যবহার করা উচিত নয়। গ্রাফিক্স প্রসেসিং ডেটা ভারী তাই একসাথে কয়েক হাজার অক্ষর পরীক্ষা করা লক্ষণীয় পিছনে হতে পারে।

-(BOOL)isEmoji:(NSString *)character {
    
    UILabel *characterRender = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
    characterRender.text = character;
    characterRender.font = [UIFont fontWithName:@"AppleColorEmoji" size:12.0f];//Note: Size 12 font is likely not crucial for this and the detector will probably still work at an even smaller font size, so if you needed to speed this checker up for serious performance you may test lowering this to a font size like 6.0
    characterRender.backgroundColor = [UIColor blackColor];//needed to remove subpixel rendering colors
    [characterRender sizeToFit];
    
    CGRect rect = [characterRender bounds];
    UIGraphicsBeginImageContextWithOptions(rect.size,YES,0.0f);
    CGContextRef contextSnap = UIGraphicsGetCurrentContext();
    [characterRender.layer renderInContext:contextSnap];
    UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    CGImageRef imageRef = [capturedImage CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;//Note: Alpha Channel not really needed, if you need to speed this up for serious performance you can refactor this pixel scanner to just RGB
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);
    
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);
    
    BOOL colorPixelFound = NO;
    
    int x = 0;
    int y = 0;
    while (y < height && !colorPixelFound) {
        while (x < width && !colorPixelFound) {
            
            NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
            
            CGFloat red = (CGFloat)rawData[byteIndex];
            CGFloat green = (CGFloat)rawData[byteIndex+1];
            CGFloat blue = (CGFloat)rawData[byteIndex+2];
            
            CGFloat h, s, b, a;
            UIColor *c = [UIColor colorWithRed:red green:green blue:blue alpha:1.0f];
            [c getHue:&h saturation:&s brightness:&b alpha:&a];//Note: I wrote this method years ago, can't remember why I check HSB instead of just checking r,g,b==0; Upon further review this step might not be needed, but I haven't tested to confirm yet. 
            
            b /= 255.0f;
            
            if (b > 0) {
                colorPixelFound = YES;
            }
            
            x++;
        }
        x=0;
        y++;
    }
    
    return colorPixelFound;
    
}

4
আমি তোমার ভাবনা পছন্দ করি! ;) - বাক্সের বাইরে!
রামন

আপনি আমাদের সাথে এই করছেন কেন? # অ্যাপল # ইউনিকোডেস্ট্যান্ডার্ড 😱🤔🤪🙈😈🤕💩
d4Rk

আমি কিছুক্ষণের মধ্যে এটির দিকে নজর দিইনি তবে আমি ভাবছি যদি আমাকে ইউআইকিওলরে রূপান্তর করতে হয় তবে এইচএসবিতে রূপান্তর করতে হবে; দেখে মনে হচ্ছে যে আমি যে আর, জি, বি সব == 0 পরীক্ষা করতে পারি? যদি কেউ চেষ্টা করে আমাকে জানান
আলবার্ট রেনশো

আমি এই সমাধানটি পছন্দ করি তবে এটি কি ℹ জাতীয় চরিত্রের সাথে ভেঙে যাবে না?
হুয়ান কার্লোস ওস্পিনা গঞ্জালেজ

4
@ জুয়ান কার্লোস ওস্পিনা গঞ্জালেজ নোপ, ইমোজি-তে একটি সাদা আই দিয়ে নীল রঙের বাক্স হিসাবে রেন্ডার। এটি একটি ভাল পয়েন্ট তুলে ধরেছে যদিও ইউআইএলবেল ফন্টটিকে বাধ্য করতে হবে AppleColorEmoji, যোগ করে এখন ব্যর্থ নিরাপদ হিসাবে, যদিও আমি মনে করি অ্যাপল সে যাইহোক এটির জন্য ডিফল্ট করবে
অ্যালবার্ট রেনশো

2

সুইফট 3.0.০.২ এর জন্য নিম্নলিখিত উত্তরটি সবচেয়ে সহজ:

class func stringContainsEmoji (string : NSString) -> Bool
{
    var returnValue: Bool = false

    string.enumerateSubstrings(in: NSMakeRange(0, (string as NSString).length), options: NSString.EnumerationOptions.byComposedCharacterSequences) { (substring, substringRange, enclosingRange, stop) -> () in

        let objCString:NSString = NSString(string:substring!)
        let hs: unichar = objCString.character(at: 0)
        if 0xd800 <= hs && hs <= 0xdbff
        {
            if objCString.length > 1
            {
                let ls: unichar = objCString.character(at: 1)
                let step1: Int = Int((hs - 0xd800) * 0x400)
                let step2: Int = Int(ls - 0xdc00)
                let uc: Int = Int(step1 + step2 + 0x10000)

                if 0x1d000 <= uc && uc <= 0x1f77f
                {
                    returnValue = true
                }
            }
        }
        else if objCString.length > 1
        {
            let ls: unichar = objCString.character(at: 1)
            if ls == 0x20e3
            {
                returnValue = true
            }
        }
        else
        {
            if 0x2100 <= hs && hs <= 0x27ff
            {
                returnValue = true
            }
            else if 0x2b05 <= hs && hs <= 0x2b07
            {
                returnValue = true
            }
            else if 0x2934 <= hs && hs <= 0x2935
            {
                returnValue = true
            }
            else if 0x3297 <= hs && hs <= 0x3299
            {
                returnValue = true
            }
            else if hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50
            {
                returnValue = true
            }
        }
    }

    return returnValue;
}

2

আমার আগে যারা লিখেছিলেন তাদের কাছে একেবারে অনুরূপ উত্তর, তবে ইমোজি স্কেলারের আপডেট সেট।

extension String {
    func isContainEmoji() -> Bool {
        let isContain = unicodeScalars.first(where: { $0.isEmoji }) != nil
        return isContain
    }
}


extension UnicodeScalar {

    var isEmoji: Bool {
        switch value {
        case 0x1F600...0x1F64F,
             0x1F300...0x1F5FF,
             0x1F680...0x1F6FF,
             0x1F1E6...0x1F1FF,
             0x2600...0x26FF,
             0x2700...0x27BF,
             0xFE00...0xFE0F,
             0x1F900...0x1F9FF,
             65024...65039,
             8400...8447,
             9100...9300,
             127000...127600:
            return true
        default:
            return false
        }
    }

}


0

উল্লিখিত কাজের জন্য একটি দুর্দান্ত সমাধান রয়েছে । তবে ইউনিকোড স্কেলারগুলির পরীক্ষা করা ইউনিকোড স্কেলারের একক চরিত্রের জন্য ভাল। এবং স্ট্রিংয়ের জন্য যথেষ্ট নমনীয় নয়।

পরিবর্তে আমরা নিয়মিত এক্সপ্রেশন ব্যবহার করতে পারি - আরও সার্বজনীন পদ্ধতির। এটি কীভাবে নীচে কাজ করে তার বিশদ বিবরণ রয়েছে। এবং এখানে সমাধান যায়।

সমাধান

সুইফ্টে আপনি পরীক্ষা করতে পারেন যে স্ট্রিং এমন একক ইমোজি চরিত্র কিনা, যেমন একটি গণনা করা সম্পত্তি সহ একটি এক্সটেনশন ব্যবহার করে:

extension String {

    var isSingleEmoji : Bool {
        if self.count == 1 {
            let emodjiGlyphPattern = "\\p{RI}{2}|(\\p{Emoji}(\\p{EMod}|\\x{FE0F}\\x{20E3}?|[\\x{E0020}-\\x{E007E}]+\\x{E007F})|[\\p{Emoji}&&\\p{Other_symbol}])(\\x{200D}(\\p{Emoji}(\\p{EMod}|\\x{FE0F}\\x{20E3}?|[\\x{E0020}-\\x{E007E}]+\\x{E007F})|[\\p{Emoji}&&\\p{Other_symbol}]))*"

            let fullRange = NSRange(location: 0, length: self.utf16.count)
            if let regex = try? NSRegularExpression(pattern: emodjiGlyphPattern, options: .caseInsensitive) {
                let regMatches = regex.matches(in: self, options: NSRegularExpression.MatchingOptions(), range: fullRange)
                if regMatches.count > 0 {
                    // if any range found — it means, that that single character is emoji
                    return true
                }
            }
        }
        return false
    }

}

এটি কীভাবে কাজ করে (বিশদে)

একটি একক ইমোজি (একটি গ্লিফ) বিভিন্ন সংকেত, অনুক্রম এবং তাদের সংমিশ্রণ দ্বারা পুনরুত্পাদন করা যেতে পারে। ইউনিকোড স্পেসিফিকেশন বিভিন্ন সম্ভাব্য ইমোজি চরিত্রের উপস্থাপনা সংজ্ঞায়িত করে।

একক-চরিত্রের ইমোজি

একটি ইমোজি চরিত্রটি একটি একক ইউনিকোড স্কেলার দ্বারা পুনরুত্পাদন করা।

ইউনিকোড ইমোজি চরিত্রটিকে এভাবে সংজ্ঞায়িত করে:

emoji_character := \p{Emoji}

তবে এর অর্থ এই নয় যে ইমোজি হিসাবে এই জাতীয় একটি চরিত্র আঁকা হবে। একটি সাধারণ সংখ্যা চিহ্ন "1" এর ইমোজি সম্পত্তিটি সত্য হলেও এটি এখনও পাঠ্য হিসাবে আঁকতে পারে। এবং এই জাতীয় চিহ্নগুলির একটি তালিকা রয়েছে: #, ©, 4, ইত্যাদি etc.

কারও মনে করা উচিত, আমরা অতিরিক্ত সম্পত্তি ব্যবহার করতে পারি: "ইমোজি_প্রেমিশন" check তবে এটি এর মতো কাজ করে না। এখানে 🏟 বা like এর মতো ইমোজি রয়েছে, যার ইমোজি_প্রেসিটিশন = মিথ্যা সম্পত্তি রয়েছে।

অক্ষরটি ডিফল্টরূপে ইমোজি হিসাবে আঁকা হয়েছে তা নিশ্চিত করার জন্য, আমাদের এটির বিভাগটি পরীক্ষা করা উচিত: এটি "অন্যান্য_সাম্বিক" হওয়া উচিত।

সুতরাং, প্রকৃতপক্ষে একক-চরিত্রের ইমোজিগুলির জন্য নিয়মিত প্রকাশটি এই হিসাবে সংজ্ঞায়িত করা উচিত:

emoji_character := \p{Emoji}&&\p{Other_symbol}

ইমোজি উপস্থাপনা সিকোয়েন্স

একটি চরিত্র যা সাধারণত পাঠ্য বা ইমোজি হিসাবে আঁকা যায়। এটির উপস্থিতি একটি বিশেষ নিম্নলিখিত প্রতীক, একটি উপস্থাপনা নির্বাচক, যা এর উপস্থাপনা প্রকারটি নির্দেশ করে তার উপর নির্ভর করে। \ x {FE0E text পাঠ্য উপস্থাপনা সংজ্ঞায়িত করে। \ x {FE0F e ইমোজি উপস্থাপনের সংজ্ঞা দেয়।

এই জাতীয় প্রতীকগুলির তালিকা [এখানে] পাওয়া যাবে (
 https://unicode.org/Public/emoji/12.1/emoji-variation-sequences.txt )।

ইউনিকোড উপস্থাপনা ক্রমটিকে এভাবে परिभाषित করে:

emoji_presentation_sequence := emoji_character emoji_presentation_selector

এটির জন্য নিয়মিত প্রকাশের ক্রম:

emoji_presentation_sequence := \p{Emoji} \x{FE0F}

ইমোজি কিক্যাপ সিকোয়েন্স

উপস্থাপনা ক্রমের সাথে সিকোয়েন্সটি খুব একই রকম দেখায় তবে এর শেষে অতিরিক্ত স্কেলার রয়েছে: \ x {20E3}} এর জন্য ব্যবহৃত সম্ভাব্য বেস স্কেলারের সুযোগটি বরং সংকীর্ণ: 0-9 # * - এবং এগুলি সবই। উদাহরণ: 1️⃣, 8️⃣, * ️⃣।

ইউনিকোড কি-ক্যাপ সিকোয়েন্সটি এভাবে সংজ্ঞায়িত করে:

emoji_keycap_sequence := [0-9#*] \x{FE0F 20E3}

এটির জন্য নিয়মিত প্রকাশ:

emoji_keycap_sequence := \p{Emoji} \x{FE0F} \x{FE0F}

ইমোজি মোডিফায়ার সিকোয়েন্স

কিছু ইমোজিদের ত্বকের স্বরের মতো পরিবর্তিত চেহারা থাকতে পারে। উদাহরণস্বরূপ ইমোজি 🧑 আলাদা হতে পারে: 🧑🧑🏻🧑🏼🧑🏽🧑🏾🧑🏿 🧑🧑🏻🧑🏼🧑🏽🧑🏾🧑🏿 এই ক্ষেত্রে ইমোজি সংজ্ঞা দেওয়ার জন্য, যাকে "ইমোজি_মডিফায়ার_বেস" বলা হয়, পরবর্তী কোনও "ইমোজি_মডিফায়ার" ব্যবহার করতে পারেন।

সাধারণভাবে এই ধরণের ক্রমটি এরকম দেখাচ্ছে:

emoji_modifier_sequence := emoji_modifier_base emoji_modifier

এটি সনাক্ত করতে আমরা একটি নিয়মিত অভিব্যক্তি ক্রম অনুসন্ধান করতে পারি:

emoji_modifier_sequence := \p{Emoji} \p{EMod}

ইমোজি ফ্ল্যাগ সিকোয়েন্স

পতাকাগুলি তাদের নির্দিষ্ট কাঠামোর সাথে ইমোজি হয়। প্রতিটি পতাকা দুটি "আঞ্চলিক_আন্দিদীকরণকারী" চিহ্ন সহ উপস্থাপিত হয়।

ইউনিকোড তাদের এ জাতীয় সংজ্ঞা দেয়:

emoji_flag_sequence := regional_indicator regional_indicator

উদাহরণস্বরূপ ইউক্রেনের পতাকাটি আসলে দুটি স্কেলারের সাথে প্রতিনিধিত্ব করে:: u {0001F1FA FA u {0001F1E6}

এটির জন্য নিয়মিত প্রকাশ:

emoji_flag_sequence := \p{RI}{2}

ইমোজি ট্যাগ সিকোয়েন্স (ইটিএস)

একটি ক্রম যা তথাকথিত ট্যাগ_বেস ব্যবহার করে, তারপরে \ x {E0020} - \ x {E007E ols এবং চিহ্ন_র চিহ্ন দ্বারা নির্ধারিত একটি কাস্টম ট্যাগ স্পেসিফিকেশন অনুসরণ করা হয় \ x {E007F}}

ইউনিকোড এটি এর মতো সংজ্ঞা দেয়:

emoji_tag_sequence := tag_base tag_spec tag_end
tag_base           := emoji_character
                    | emoji_modifier_sequence
                    | emoji_presentation_sequence
tag_spec           := [\x{E0020}-\x{E007E}]+
tag_end            := \x{E007F}

আশ্চর্যের বিষয় হ'ল ইউনিকোড ইডি -14 এ - তে ইমোজি_মডিফায়ার_সেক্সেন্স বা ইমোজি_প্রেসেন্টেশন_সেক্সেন্সের ভিত্তিতে ট্যাগটিকে মঞ্জুরি দেয় । একই সময়ে একই ডকুমেন্টেশনে নিয়মিত প্রকাশিত অভিব্যক্তিগুলিতে তারা কেবলমাত্র একটি ইমোজি চরিত্রের উপর ভিত্তি করে ক্রমটি চেক করে বলে মনে হয়।

ইউনিকোড 12.1 ইমোজি তালিকায় এই জাতীয় তিনটি ইমোজি সংজ্ঞা রয়েছে। এগুলির সবগুলিই যুক্তরাজ্যের দেশগুলির পতাকা: ইংল্যান্ড 🏴󠁧󠁢󠁥󠁮󠁧󠁿, স্কটল্যান্ড 🏴󠁧󠁢󠁳󠁣󠁴󠁿 এবং ওয়েলস 🏴󠁧󠁢󠁷󠁬󠁳󠁿 এবং এগুলি সবই একক ইমোজি চরিত্রের উপর ভিত্তি করে। সুতরাং, আমরা কেবল এই জাতীয় ক্রমটি আরও ভালভাবে পরীক্ষা করতে চাই।

নিয়মিত প্রকাশ:

\p{Emoji} [\x{E0020}-\x{E007E}]+ \x{E007F}

ইমোজি জিরো-প্রস্থের সংযুক্তকারী সিকোয়েন্স (জেডডাব্লুজে ক্রম)

শূন্য-প্রস্থের জোড়াকারটি একটি স্কেলার \ x {200D}} এর সাহায্যে বেশ কয়েকটি অক্ষর, যা ইতোমধ্যে নিজের দ্বারা ইমোজিসকে নতুন একটিতে যুক্ত করা যেতে পারে।

উদাহরণস্বরূপ, "বাবা, পুত্র এবং কন্যার পরিবার" ইমোজি 👨‍👧‍👦 পিতা father কন্যা এবং পুত্রের মিশ্রণ দ্বারা পুনরুত্পাদন করা হয়েছে - ইমোজিস জেডডব্লিউজে প্রতীকগুলির সাথে একসাথে আটকানো হয়েছে।

এটি একক ইমোজি অক্ষর, উপস্থাপনা এবং সংশোধক ক্রমসমূহ একসাথে থাকা উপাদানগুলিকে একত্রে রাখার অনুমতি দেওয়া হয়।

সাধারণভাবে এই ক্রমগুলির জন্য নিয়মিত অভিব্যক্তিটি দেখতে এইরকম লাগে:

emoji_zwj_sequence := emoji_zwj_element (\x{200d} emoji_zwj_element )+

তাদের সকলের জন্য নিয়মিত এক্সপ্রেশন

উপরে উল্লিখিত সমস্ত ইমোজি উপস্থাপনাগুলি একক নিয়মিত অভিব্যক্তি দ্বারা বর্ণনা করা যেতে পারে:

\p{RI}{2}
| ( \p{Emoji} 
    ( \p{EMod} 
    | \x{FE0F}\x{20E3}? 
    | [\x{E0020}-\x{E007E}]+\x{E007F} 
    ) 
  | 
[\p{Emoji}&&\p{Other_symbol}] 
  )
  ( \x{200D}
    ( \p{Emoji} 
      ( \p{EMod} 
      | \x{FE0F}\x{20E3}? 
      | [\x{E0020}-\x{E007E}]+\x{E007F} 
      ) 
    | [\p{Emoji}&&\p{Other_symbol}] 
    ) 
  )*

-1

আমার একই সমস্যা ছিল এবং একটি Stringএবং Characterএক্সটেনশানগুলি শেষ করেছিলাম ।

কোডটি পোস্ট করতে খুব দীর্ঘ কারণ এটি প্রকৃতপক্ষে সমস্ত ইমোজিদের তালিকাভুক্ত করেছে (অফিসিয়াল ইউনিকোড তালিকা v5.0 থেকে) আপনি CharacterSetএটি এখানে পেতে পারেন:

https://github.com / পিটারওয়িলসন / স্ট্রিং ইমোজি

ধ্রুবক

ইমোজিচরেক্টারসেট: ক্যারেক্টারসেট দিন

সমস্ত পরিচিত ইমোজি সমন্বিত অক্ষর সেট (অফিসিয়াল ইউনিকোড তালিকায় বর্ণিত 5.0 http://unicode.org/emoji/charts-5.0/emoji-list.html )

স্ট্রিং

var isEmoji: Bool {get}

Stringউদাহরণটি কোনও পরিচিত একক ইমোজি চরিত্রের প্রতিনিধিত্ব করে কিনা

print("".isEmoji) // false
print("😁".isEmoji) // true
print("😁😜".isEmoji) // false (String is not a single Emoji)
ভের রয়েছে ইমোজি: বুল {পেতে}

Stringউদাহরণটিতে একটি পরিচিত ইমোজি চরিত্র রয়েছে কিনা

print("".containsEmoji) // false
print("😁".containsEmoji) // true
print("😁😜".containsEmoji) // true
var ইউনিকোডনাম: স্ট্রিং {get}

স্ট্রিংয়ের অনুলিপিটিতে kCFStringTransformToUnicodeName- প্রয়োগ CFStringTransformকরে

print("á".unicodeName) // \N{LATIN SMALL LETTER A WITH ACUTE}
print("😜".unicodeName) // "\N{FACE WITH STUCK-OUT TONGUE AND WINKING EYE}"
var niceUnicodeName: স্ট্রিং {get}

উপসর্গ এবং প্রত্যয় মুছে ফেলা সহ kCFStringTransformToUnicodeName- এর ফলাফল প্রদান করেCFStringTransform\N{}

print("á".unicodeName) // LATIN SMALL LETTER A WITH ACUTE
print("😜".unicodeName) // FACE WITH STUCK-OUT TONGUE AND WINKING EYE

চরিত্র

var isEmoji: Bool {get}

Characterউদাহরণটি কোনও পরিচিত ইমোজি চরিত্রের প্রতিনিধিত্ব করে কিনা

print("".isEmoji) // false
print("😁".isEmoji) // true
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.