我有彩色图像。我希望在触摸图像时返回像素值。 所以,我尝试了以下代码:
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
float x, y;
for (UITouch *touch in touches) {
x = [touch locationInView:imageView].x;
y = [touch locationInView:imageView].y;
if ((x >= 0) && (x <= imageView.frame.size.width) && (y >= 0) && (y <= imageView.frame.size.height)) {
[self getRGBAFromImage:imageView.image atX:x andY:y];
}
}
}
- (void)getRGBAFromImage:(UIImage *)image atX:(int)xx andY:(int)yy {
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
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);
int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel;
CGFloat red = (rawData[byteIndex] * 1.0) ;
CGFloat green = (rawData[byteIndex + 1] * 1.0) ;
CGFloat blue = (rawData[byteIndex + 2] * 1.0) ;
CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;
self.textView.textColor=[UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:alpha];
free(rawData);
}
这将返回像素,但不是正确的像素!例如:ImageView中的触摸颜色为红色,但我的textView文本不是红色。
请帮我确认我的代码。
谢谢!
答案 0 :(得分:0)
以下是我需要获取图像上特定像素颜色时使用的UIImage类别:
@implementation UIImage (ColorImage)
/*
Returns the color of the image pixel at point. Returns nil if point lies outside of the image bounds.
If the point coordinates contains a decimal part, it will be truncated (trunc).
This method retreives the pixel data of the image by drawing the specific pixel onto a bitmap.
To query pixel colors of the same image many times, it is best to cache the drawn image for better performance.
*/
- (UIColor *)colorAtPixel:(CGPoint)point {
// Cancel if the point is outside of the image coordinates
if (!CGRectContainsPoint(CGRectMake(0.0f, 0.0f, self.size.width, self.size.height), point)) {
return nil;
}
// Create a 1x1 pixel byte array and bitmap context to draw the pixel onto.
// Reference: http://stackoverflow.com/questions/1042830/retrieving-a-pixel-alpha-value-for-a-uiimage
NSInteger pointX = trunc(point.x);
NSInteger pointY = trunc(point.y);
CGImageRef cgImage = self.CGImage;
NSUInteger width = CGImageGetWidth(cgImage);
NSUInteger height = CGImageGetHeight(cgImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
int bytesPerPixel = 4;
int bytesPerRow = bytesPerPixel * 1;
NSUInteger bitsPerComponent = 8;
unsigned char pixelData[4] = { 0, 0, 0, 0 };
CGContextRef context = CGBitmapContextCreate( pixelData, 1, 1, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextSetBlendMode(context, kCGBlendModeCopy);
// Draw the pixel we are interested in
CGContextTranslateCTM(context, -pointX, -pointY);
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, (CGFloat)width, (CGFloat)height), cgImage);
CGContextRelease(context);
// Convert the color values [0...255] to floats [0.0f...1.0f]
CGFloat r = (CGFloat)pixelData[0] / 255.0f;
CGFloat g = (CGFloat)pixelData[1] / 255.0f;
CGFloat b = (CGFloat)pixelData[2] / 255.0f;
CGFloat a = (CGFloat)pixelData[3] / 255.0f;
return [UIColor colorWithRed:r green:g blue:b alpha:a];
}
@end
您可以直接在-colorAtPixel
上致电UIImage
,它会将颜色返回为UIColor
。
答案 1 :(得分:0)
如果要在 Swift 中实现相同的功能,可以尝试以下简单的实现。
import UIKit
extension UIImage {
/*
This will work for both RGB and Gray ColorSpace
*/
func getPixelColor(pos: CGPoint) -> UIColor {
if let pixelData = self.cgImage?.dataProvider?.data {
let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4
let red = CGFloat(data[pixelInfo]) / CGFloat(255.0)
let green = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
let blue = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
let alpha = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)
return UIColor(red: red, green: green, blue: blue, alpha: alpha)
}
return UIColor.black
}
func getPixelValue(pos: CGPoint) -> Int {
if let pixelData = self.cgImage?.dataProvider?.data {
let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4
let red = CGFloat(data[pixelInfo])
let green = CGFloat(data[pixelInfo+1])
let blue = CGFloat(data[pixelInfo+2])
//let alpha = CGFloat(data[pixelInfo+3])
return Int((red + green + blue)/3)
}
return 0
}
}