Skip to content

Instantly share code, notes, and snippets.

@hirohitokato
Created October 25, 2022 09:24
Show Gist options
  • Save hirohitokato/92276b09a1b9ae7a1ffe978f91417c9f to your computer and use it in GitHub Desktop.
Save hirohitokato/92276b09a1b9ae7a1ffe978f91417c9f to your computer and use it in GitHub Desktop.
UIImageViewで表示している画像の、特定位置のピクセル色を求めるextension
import UIKit
extension UIImageView {
/// UIImageView上での座標が指す色をUIColorで返す。画像が未設定の場合はnilを返す
///
/// 以下のように使う.
///
/// @objc func tappedImage(_ sender: UITapGestureRecognizer) {
/// let point = sender.location(in: self)
/// let color = self.pixelColor(at: point) // <- here
/// :
/// }
///
/// - Attention: 座標pointはUIImageViewにおける座標であることに注意。
/// - SeeAlso: [UIImageにCIFilterをかけたimageのタップ座標から、そのpixelの色を取得したい。](https://teratail.com/questions/29984)
/// - Parameter point: UIImageViewにおける座標
/// - Returns: 座標pointにおける画像の色
func pixelColor(at point: CGPoint) -> UIColor? {
guard let cgImage = self.image?.cgImage else { return nil }
guard let pixelData = cgImage.dataProvider?.data else { return nil }
let data = CFDataGetBytePtr(pixelData)!
// UIImageViewでの座標 → 画像上の座標
let xScale = frame.width / bounds.width
let yScale = frame.height / bounds.height
let imagePoint = CGPoint(x: (point.x / self.frame.width) * CGFloat(cgImage.width) * xScale,
y: (point.y / self.frame.height) * CGFloat(cgImage.height) * yScale)
// 1ピクセルのバイト数
let bytesPerPixel = cgImage.bitsPerPixel / 8
// 1ラインのバイト数
let bytesPerRow = cgImage.bytesPerRow
//タップした位置の座標にあたるアドレスを算出
let pixelAddress = Int(imagePoint.y) * bytesPerRow + Int(imagePoint.x) * bytesPerPixel
//それぞれRGBAの値をとる
let r = CGFloat(data[pixelAddress]) / CGFloat(255.0)
let g = CGFloat(data[pixelAddress+1]) / CGFloat(255.0)
let b = CGFloat(data[pixelAddress+2]) / CGFloat(255.0)
let a = CGFloat(data[pixelAddress+3]) / CGFloat(255.0)
return UIColor(red: r, green: g, blue: b, alpha: a)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment