pantalla hora españa como color cambio cambiar apple iphone cocoa-touch image bitmap

hora - iphone xs



Cómo obtener los valores RGB para un píxel en una imagen en el iphone (8)

No sé cómo indexar los datos de imagen correctamente en función de la cordinación X, Y determinada. ¿Alguien sabe?

pixelPosition = (x + (y * ((ancho de la imagen) * BytesPerPixel)));

// pitch no es un problema con este dispositivo por lo que sé y se puede dejar cero ... // (o sacado de las matemáticas).

Estoy escribiendo una aplicación para iPhone y necesito implementar esencialmente algo equivalente a la herramienta ''cuentagotas'' en photoshop, donde puedes tocar un punto de la imagen y capturar los valores RGB para el píxel en cuestión para determinar y combinar su color. Obtener el UIImage es la parte fácil, pero ¿hay alguna forma de convertir los datos de UIImage en una representación de mapa de bits en la que pueda extraer esta información para un píxel determinado? Una muestra de código de trabajo sería muy apreciada, y tenga en cuenta que no me preocupa el valor alfa.


Un poco más de detalle ...

Publiqué esta tarde con una consolidación y una pequeña adición a lo que se había dicho en esta página, que se puede encontrar en la parte inferior de esta publicación. Estoy editando la publicación en este momento, sin embargo, para publicar lo que propongo (al menos para mis requisitos, que incluyen la modificación de datos de píxeles) un mejor método, ya que proporciona datos de escritura (mientras que, según entiendo, el método proporcionado por publicaciones anteriores y en la parte inferior de esta publicación proporciona una referencia de solo lectura a los datos).

Método 1: información de píxeles que se puede escribir

  1. Definí constantes

    #define RGBA 4 #define RGBA_8_BIT 8

  2. En mi subclase UIImage, he declarado variables de instancia:

    size_t bytesPerRow; size_t byteCount; size_t pixelCount; CGContextRef context; CGColorSpaceRef colorSpace; UInt8 *pixelByteData; // A pointer to an array of RGBA bytes in memory RPVW_RGBAPixel *pixelData;

  3. La estructura de píxeles (con alfa en esta versión)

    typedef struct RGBAPixel { byte red; byte green; byte blue; byte alpha; } RGBAPixel;

  4. Función de mapa de bits (devuelve RGBA precalculado, divida RGB por A para obtener RGB sin modificar):

    -(RGBAPixel*) bitmap { NSLog( @"Returning bitmap representation of UIImage." ); // 8 bits each of red, green, blue, and alpha. [self setBytesPerRow:self.size.width * RGBA]; [self setByteCount:bytesPerRow * self.size.height]; [self setPixelCount:self.size.width * self.size.height]; // Create RGB color space [self setColorSpace:CGColorSpaceCreateDeviceRGB()]; if (!colorSpace) { NSLog(@"Error allocating color space."); return nil; } [self setPixelData:malloc(byteCount)]; if (!pixelData) { NSLog(@"Error allocating bitmap memory. Releasing color space."); CGColorSpaceRelease(colorSpace); return nil; } // Create the bitmap context. // Pre-multiplied RGBA, 8-bits per component. // The source image format will be converted to the format specified here by CGBitmapContextCreate. [self setContext:CGBitmapContextCreate( (void*)pixelData, self.size.width, self.size.height, RGBA_8_BIT, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast )]; // Make sure we have our context if (!context) { free(pixelData); NSLog(@"Context not created!"); } // Draw the image to the bitmap context. // The memory allocated for the context for rendering will then contain the raw image pixelData in the specified color space. CGRect rect = { { 0 , 0 }, { self.size.width, self.size.height } }; CGContextDrawImage( context, rect, self.CGImage ); // Now we can get a pointer to the image pixelData associated with the bitmap context. pixelData = (RGBAPixel*) CGBitmapContextGetData(context); return pixelData; }

Datos de solo lectura (información previa) - método 2:

Paso 1. Declaré un tipo para byte:

typedef unsigned char byte;

Paso 2. Declaré una estructura para que corresponda a un píxel:

typedef struct RGBPixel{ byte red; byte green; byte blue; } RGBPixel;

Paso 3. Subclassed UIImageView y declarado (con las propiedades sintetizadas correspondientes):

// Reference to Quartz CGImage for receiver (self) CFDataRef bitmapData; // Buffer holding raw pixel data copied from Quartz CGImage held in receiver (self) UInt8* pixelByteData; // A pointer to the first pixel element in an array RGBPixel* pixelData;

Paso 4. Código de la subclase. Puse un método llamado mapa de bits (para devolver los datos del mapa de bits):

//Get the bitmap data from the receiver''s CGImage (see UIImage docs) [self setBitmapData: CGDataProviderCopyData(CGImageGetDataProvider([self CGImage]))]; //Create a buffer to store bitmap data (unitialized memory as long as the data) [self setPixelBitData:malloc(CFDataGetLength(bitmapData))]; //Copy image data into allocated buffer CFDataGetBytes(bitmapData,CFRangeMake(0,CFDataGetLength(bitmapData)),pixelByteData); //Cast a pointer to the first element of pixelByteData //Essentially what we''re doing is making a second pointer that divides the byteData''s units differently - instead of dividing each unit as 1 byte we will divide each unit as 3 bytes (1 pixel). pixelData = (RGBPixel*) pixelByteData; //Now you can access pixels by index: pixelData[ index ] NSLog(@"Pixel data one red (%i), green (%i), blue (%i).", pixelData[0].red, pixelData[0].green, pixelData[0].blue); //You can determine the desired index by multiplying row * column. return pixelData;

Paso 5. Hice un método de acceso:

-(RGBPixel*)pixelDataForRow:(int)row column:(int)column{ //Return a pointer to the pixel data return &pixelData[row * column]; }


¡Gracias a todos! Al juntar algunas de estas respuestas obtengo:

- (UIColor*)colorFromImage:(UIImage*)image sampledAtPoint:(CGPoint)p { CGImageRef cgImage = [image CGImage]; CGDataProviderRef provider = CGImageGetDataProvider(cgImage); CFDataRef bitmapData = CGDataProviderCopyData(provider); const UInt8* data = CFDataGetBytePtr(bitmapData); size_t bytesPerRow = CGImageGetBytesPerRow(cgImage); size_t width = CGImageGetWidth(cgImage); size_t height = CGImageGetHeight(cgImage); int col = p.x*(width-1); int row = p.y*(height-1); const UInt8* pixel = data + row*bytesPerRow+col*4; UIColor* returnColor = [UIColor colorWithRed:pixel[0]/255. green:pixel[1]/255. blue:pixel[2]/255. alpha:1.0]; CFRelease(bitmapData); return returnColor; }

Esto solo toma un rango de puntos de 0.0-1.0 para ambos x e y. Ejemplo:

UIColor* sampledColor = [self colorFromImage:image sampledAtPoint:CGPointMake(p.x/imageView.frame.size.width, p.y/imageView.frame.size.height)];

Esto funciona genial para mí Estoy haciendo un par de suposiciones como bits por píxel y espacio de color RGBA, pero esto debería funcionar para la mayoría de los casos.

Otra nota - para mí funciona tanto en el simulador como en el dispositivo - He tenido problemas con eso en el pasado debido a la optimización PNG que sucedió cuando se encendió en el dispositivo.


Aquí está mi solución para muestrear el color de un UIImage.

Este enfoque representa el píxel solicitado en un búfer RGBA de 1px de gran tamaño y devuelve los valores de color resultantes como un objeto UIColor. Esto es mucho más rápido que la mayoría de los otros enfoques que he visto y usa muy poca memoria.

Esto debería funcionar bastante bien para algo así como un selector de color, donde normalmente solo necesitas el valor de un píxel específico en un momento dado.

Uiimage + Picker.h

#import <UIKit/UIKit.h> @interface UIImage (Picker) - (UIColor *)colorAtPosition:(CGPoint)position; @end

Uiimage + Picker.m

#import "UIImage+Picker.h" @implementation UIImage (Picker) - (UIColor *)colorAtPosition:(CGPoint)position { CGRect sourceRect = CGRectMake(position.x, position.y, 1.f, 1.f); CGImageRef imageRef = CGImageCreateWithImageInRect(self.CGImage, sourceRect); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); unsigned char *buffer = malloc(4); CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big; CGContextRef context = CGBitmapContextCreate(buffer, 1, 1, 8, 4, colorSpace, bitmapInfo); CGColorSpaceRelease(colorSpace); CGContextDrawImage(context, CGRectMake(0.f, 0.f, 1.f, 1.f), imageRef); CGImageRelease(imageRef); CGContextRelease(context); CGFloat r = buffer[0] / 255.f; CGFloat g = buffer[1] / 255.f; CGFloat b = buffer[2] / 255.f; CGFloat a = buffer[3] / 255.f; free(buffer); return [UIColor colorWithRed:r green:g blue:b alpha:a]; } @end


La respuesta de Lajos funcionó para mí. Para obtener los datos de píxeles como una matriz de bytes, hice esto:

UInt8* data = CFDataGetBytePtr(bitmapData);

Más información: documentation CFDataRef.

Además, recuerde incluir CoreGraphics.framework


No puede acceder directamente a los datos de mapa de bits de un UIImage.

Necesita obtener la representación CGImage del UIImage. A continuación, obtenga el proveedor de datos de CGImage, a partir de eso una representación CFData del mapa de bits. Asegúrese de liberar el CFData cuando haya terminado.

CGImageRef cgImage = [image CGImage]; CGDataProviderRef provider = CGImageGetDataProvider(cgImage); CFDataRef bitmapData = CGDataProviderCopyData(provider);

Es probable que desee ver la información de mapa de bits de CGImage para obtener el orden de píxeles, las dimensiones de la imagen, etc.


Para hacer algo similar en mi aplicación, creé un pequeño CGImageContext fuera de pantalla, y luego presenté el UIImage en él. Esto me permitió una forma rápida de extraer un número de píxeles a la vez. Esto significa que puede configurar el mapa de bits objetivo en un formato que le resulte fácil de analizar, y permita que CoreGraphics haga el trabajo duro de convertir entre modelos de color o formatos de mapa de bits.


Utilice ANImageBitmapRep que proporciona acceso de nivel de píxel (lectura / escritura).