在Swift中获取某个像素(由CGPoint指定)的像素颜色时,我遇到了很大的困难。到目前为止,我的代码如下:
@IBOutlet weak var graphImage: UIImageView!
var image : UIImage?
override func viewDidLoad() {
super.viewDidLoad()
}
func getPixelColor(pos: CGPoint) -> UIColor {
var pixelData = CGDataProviderCopyData(CGImageGetDataProvider(self.graphImage.image!.CGImage))
var data : UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
var pixelInfo : Int = ((Int(graphImage.image!.size.width) * Int(pos.y) + Int(pos.x)*4))
let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
let g = CGFloat(data[pixelInfo]+1) / CGFloat(255.0)
let b = CGFloat(data[pixelInfo]+2) / CGFloat(255.0)
let a = CGFloat(data[pixelInfo]+3) / CGFloat(255.0)
return UIColor(red: r, green: g, blue: b, alpha: a)
}
@IBAction func playTapped(sender: AnyObject) {
getPixelColor(CGPoint(x: 100.0, y: 100.0))
}
在点击play之后,我的应用程序崩溃了,行"let g= CGFloat...“我根本看不到任何错误,尽管我对任何与图像有关的事情都是相当陌生的。我想知道我是否需要使用不同类型的图像,或者我的pixelInfo变量中是否有什么地方出错。顺便说一句,我从How do I get the color of a pixel in a UIImage with Swift?获得了大部分代码。谁能指出可能的问题是什么?任何帮助都将不胜感激!
发布于 2016-01-27 15:18:23
我以前做过类似的事情。我所做的是创建一个名为PixelExtractor的单独类。
class PixelExtractor: NSObject {
let image: CGImage
let context: CGContextRef?
var width: Int {
get {
return CGImageGetWidth(image)
}
}
var height: Int {
get {
return CGImageGetHeight(image)
}
}
init(img: CGImage) {
image = img
context = PixelExtractor.createBitmapContext(img)
}
class func createBitmapContext(img: CGImage) -> CGContextRef {
// Get image width, height
let pixelsWide = CGImageGetWidth(img)
let pixelsHigh = CGImageGetHeight(img)
let bitmapBytesPerRow = pixelsWide * 4
let bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh)
// Use the generic RGB color space.
let colorSpace = CGColorSpaceCreateDeviceRGB()
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
let bitmapData = malloc(bitmapByteCount)
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.PremultipliedFirst.rawValue)
let size = CGSizeMake(CGFloat(pixelsWide), CGFloat(pixelsHigh))
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
// create bitmap
let context = CGBitmapContextCreate(bitmapData, pixelsWide, pixelsHigh, 8,
bitmapBytesPerRow, colorSpace, bitmapInfo.rawValue)
// draw the image onto the context
let rect = CGRect(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)
CGContextDrawImage(context, rect, img)
return context!
}
func colorAt(x x: Int, y: Int)->UIColor {
assert(0<=x && x<width)
assert(0<=y && y<height)
let uncastedData = CGBitmapContextGetData(context)
let data = UnsafePointer<UInt8>(uncastedData)
let offset = 4 * (y * width + x)
let alpha: UInt8 = data[offset]
let red: UInt8 = data[offset+1]
let green: UInt8 = data[offset+2]
let blue: UInt8 = data[offset+3]
let color = UIColor(red: CGFloat(red)/255.0, green: CGFloat(green)/255.0, blue: CGFloat(blue)/255.0, alpha: CGFloat(alpha)/255.0)
return color
}
}
发布于 2017-01-27 07:23:10
jasonnoahchoi给出了一个很好的答案-如果你在转换到Swift 3.0时遇到了问题,可以尝试使用相同的代码,并进行以下更改:
class PixelExtractor: NSObject {
let image: CGImage
let context: CGContext?
var width: Int {
get {
return image.width
}
}
var height: Int {
get {
return image.height
}
}
init(img: CGImage) {
image = img
context = PixelExtractor.createBitmapContext(cgImage: img)
}
class func createBitmapContext(cgImage: CGImage) -> CGContext {
// Get image width, height
let pixelsWide = cgImage.width
let pixelsHigh = cgImage.height
let bitmapBytesPerRow = pixelsWide * 4
let bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh)
// Use the generic RGB color space.
let colorSpace = CGColorSpaceCreateDeviceRGB()
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
let bitmapData = malloc(bitmapByteCount)
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)
let size = CGSize(width: pixelsWide, height: pixelsHigh)
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
// create bitmap
let context = CGContext(data: bitmapData, width: pixelsWide, height: pixelsHigh, bitsPerComponent: 8,
bytesPerRow: bitmapBytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo.rawValue)
// draw the image onto the context
let rect = CGRect(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)
context?.draw(cgImage, in: rect)
return context!
}
private func colorAt(x: Int, y: Int) -> UIColor {
assert(0<=x && x<width)
assert(0<=y && y<height)
let data = context!.data!
let offset = 4 * (y * width + x)
let alpha = CGFloat(data.load(fromByteOffset: offset, as: UInt8.self)) / 255.0
let red = CGFloat(data.load(fromByteOffset: offset + 1, as: UInt8.self)) / 255.0
let green = CGFloat(data.load(fromByteOffset: offset + 2, as: UInt8.self)) / 255.0
let blue = CGFloat(data.load(fromByteOffset: offset + 3, as: UInt8.self)) / 255.0
let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
return color
}
}
发布于 2019-05-15 03:36:13
jasonnoahchoi答案的Swift 5版本
class PixelExtractor: NSObject {
let image: CGImage
let context: CGContext?
var width: Int {
get {
return image.width
}
}
var height: Int {
get {
return image.height
}
}
init(img: CGImage) {
image = img
context = PixelExtractor.createBitmapContext(img: img)
}
class func createBitmapContext(img: CGImage) -> CGContext {
// Get image width, height
let pixelsWide = img.width
let pixelsHigh = img.height
let bitmapBytesPerRow = pixelsWide * 4
let bitmapByteCount = bitmapBytesPerRow * Int(pixelsHigh)
// Use the generic RGB color space.
let colorSpace = CGColorSpaceCreateDeviceRGB()
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
let bitmapData = malloc(bitmapByteCount)
let bitmapInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedFirst.rawValue)
let size = CGSize(width: CGFloat(pixelsWide), height: CGFloat(pixelsHigh))
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
// create bitmap
let context = CGContext(data: bitmapData,
width: pixelsWide,
height: pixelsHigh,
bitsPerComponent: 8,
bytesPerRow: bitmapBytesPerRow,
space: colorSpace,
bitmapInfo: bitmapInfo.rawValue)
// draw the image onto the context
let rect = CGRect(x: 0, y: 0, width: pixelsWide, height: pixelsHigh)
context?.draw(img, in: rect)
return context!
}
func colorAt(x: Int, y: Int)->UIColor {
assert(0<=x && x<width)
assert(0<=y && y<height)
guard let pixelBuffer = context?.data else { return .white }
let data = pixelBuffer.bindMemory(to: UInt8.self, capacity: width * height)
let offset = 4 * (y * width + x)
let alpha: UInt8 = data[offset]
let red: UInt8 = data[offset+1]
let green: UInt8 = data[offset+2]
let blue: UInt8 = data[offset+3]
let color = UIColor(red: CGFloat(red)/255.0, green: CGFloat(green)/255.0, blue: CGFloat(blue)/255.0, alpha: CGFloat(alpha)/255.0)
return color
}
}
https://stackoverflow.com/questions/35029672
复制相似问题