Para su información, combiné la respuesta de Keremk con mi esquema original, limpié los errores tipográficos, lo generalicé para devolver una variedad de colores y conseguí que todo se compilara. Aquí está el resultado:
+ (NSArray*)getRGBAsFromImage:(UIImage*)image atX:(int)x andY:(int)y count:(int)count
{
NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];
// First get the image into your data buffer
CGImageRef imageRef = [image 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;
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);
// Now your rawData contains the image data in the RGBA8888 pixel format.
NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
for (int i = 0 ; i < count ; ++i)
{
CGFloat alpha = ((CGFloat) rawData[byteIndex + 3] ) / 255.0f;
CGFloat red = ((CGFloat) rawData[byteIndex] ) / alpha;
CGFloat green = ((CGFloat) rawData[byteIndex + 1] ) / alpha;
CGFloat blue = ((CGFloat) rawData[byteIndex + 2] ) / alpha;
byteIndex += bytesPerPixel;
UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
[result addObject:acolor];
}
free(rawData);
return result;
}
getRGBAsFromImage:image atX:0 andY:0 count:image.size.width*image.size.height
Para obtener RGBA para la última fila de una imagen:getRGBAsFromImage:image atX:0 andY:image.size.height-1 count:image.size.width
Una forma de hacerlo es dibujar la imagen en un contexto de mapa de bits respaldado por un búfer determinado para un espacio de color determinado (en este caso, es RGB): (tenga en cuenta que esto copiará los datos de la imagen a ese búfer, por lo que debe hacerlo desea almacenarlo en caché en lugar de hacer esta operación cada vez que necesite obtener valores de píxeles)
Vea a continuación como muestra:
fuente
CGContextDrawImage
requiere tres argumentos y arriba solo se dan dos ... Creo que debería serloCGContextDrawImage(context, CGRectMake(0, 0, width, height), image)
Preguntas y respuestas técnicas de Apple QA1509 muestra el siguiente enfoque simple:
Utilícelo
CFDataGetBytePtr
para llegar a los bytes reales (y variosCGImageGet*
métodos para comprender cómo interpretarlos).fuente
No podía creer que no haya una sola respuesta correcta aquí. No es necesario asignar punteros, y los valores no multiplicados aún deben normalizarse. Para ir al grano, aquí está la versión correcta para Swift 4.
UIImage
Solo para usar.cgImage
.La razón por la que primero tiene que dibujar / convertir la imagen en un búfer es porque las imágenes pueden tener varios formatos diferentes. Este paso es necesario para convertirlo a un formato consistente que pueda leer.
fuente
let imageObj = UIImage(named:"greencolorImg.png"); imageObj.cgImage?.colors(at: [pt1, pt2])
pt1
ypt2
sonCGPoint
variables.Aquí hay un subproceso SO en el que @Matt procesa solo el píxel deseado en un contexto de 1x1 desplazando la imagen para que el píxel deseado se alinee con el píxel en el contexto.
fuente
fuente
UIImage es un contenedor, los bytes son CGImage o CIImage
De acuerdo con la Referencia de Apple sobre UIImage, el objeto es inmutable y no tiene acceso a los bytes de respaldo. Si bien es cierto que puede acceder a los datos de CGImage si completó el
UIImage
con unCGImage
(explícita o implícitamente), volveráNULL
siUIImage
está respaldado por ayCIImage
viceversa.Trucos comunes para solucionar este problema
Como se indicó, sus opciones son
Ninguno de estos son trucos particularmente buenos si desea resultados que no sean datos ARGB, PNG o JPEG y los datos no estén respaldados por CIImage.
Mi recomendación, prueba CIImage
Al desarrollar su proyecto, puede tener más sentido evitar el UIImage por completo y elegir otra cosa. UIImage, como un contenedor de imágenes Obj-C, a menudo está respaldado por CGImage hasta el punto en que lo damos por sentado. CIImage tiende a ser un mejor formato envoltorio, ya que puede usar un CIContext para obtener el formato que desee sin necesidad de saber cómo se creó. En su caso, obtener el mapa de bits sería una cuestión de llamar
- render: toBitmap: rowBytes: límites: formato: colorSpace:
Como una ventaja adicional, puede comenzar a hacer buenas manipulaciones en la imagen encadenando filtros en la imagen. Esto resuelve muchos de los problemas donde la imagen está al revés o necesita ser rotada / escalada, etc.
fuente
Sobre la base de la respuesta de Olie y Algal, aquí hay una respuesta actualizada para Swift 3
rápido
fuente
Versión Swift 5
Las respuestas dadas aquí están desactualizadas o son incorrectas porque no tienen en cuenta lo siguiente:
image.size.width
/image.size.height
.UIView.drawHierarchy(in:afterScreenUpdates:)
método puede producir imágenes BGRA.CGImage
, el tamaño de una fila de píxeles en bytes puede ser mayor que la mera multiplicación del ancho de píxeles por 4.El siguiente código es para proporcionar una solución universal de Swift 5 para obtener
UIColor
un píxel para todos esos casos especiales. El código está optimizado para facilidad de uso y claridad, no para rendimiento.fuente
componentLayout
falta el caso cuando sólo hay alfa,.alphaOnly
.UIImage
, que es lo que haría antes de comenzar a leer sus colores de píxeles.Basado en diferentes respuestas pero principalmente en esto , esto funciona para lo que necesito:
Como resultado de estas líneas, tendrá un píxel en formato AARRGGBB con alfa siempre configurado en FF en el entero sin signo de 4 bytes
pixel1
.fuente
Para acceder a los valores RGB sin procesar de un UIImage en Swift 5, use la imagen CG subyacente y su proveedor de datos:
https://www.ralfebert.de/ios/examples/image-processing/uiimage-raw-pixels/
fuente