uiimage - online - rgba generador
Problema que reconstituye el UIImage de los datos de bytes de pĂxeles RGBA (2)
El problema de transparencia alfa se ha solucionado en el último empuje github. https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m
La solución era usar el siguiente código con kCGImageAlphaPremultipliedLast lógicamente ORed en bitmapInfo en la función. El bitmapInfo también se usó para aumentar el CGContextRef, además de CGImageRef. Los formatos deben ser los mismos para ambos parámetros de bitmapInfo.
+ (UIImage *) convertBitmapRGBA8ToUIImage:(unsigned char *) buffer
withWidth:(int) width
withHeight:(int) height;
Extracto del código:
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef iref = CGImageCreate(width,
height,
bitsPerComponent,
bitsPerPixel,
bytesPerRow,
colorSpaceRef,
bitmapInfo,
provider, // data provider
NULL, // decode
YES, // should interpolate
renderingIntent);
uint32_t* pixels = (uint32_t*)malloc(bufferLength);
if(pixels == NULL) {
NSLog(@"Error: Memory not allocated for bitmap");
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpaceRef);
CGImageRelease(iref);
return nil;
}
CGContextRef context = CGBitmapContextCreate(pixels,
width,
height,
bitsPerComponent,
bytesPerRow,
colorSpaceRef,
bitmapInfo);
Necesito crear 12 imágenes en color desde una sola imagen en escala de grises (rojo, naranja, amarillo, etc.)
La imagen de origen es en realidad un PNG, RGBA:
Estoy usando una biblioteca que encontré ( https://github.com/PaulSolt/UIImage-Conversion/ ) para descomponer el UIImage en una matriz de bytes RGBA que luego proceso píxel por píxel, y uso la misma biblioteca para reconstituir una nueva UIImage.
Este es mi código:
- (UIImage*) cloneWithTint3: (CGColorRef) cgTint
{
enum { R, G, B, A };
// - - -
assert( CGColorGetNumberOfComponents( cgTint ) == 4 );
const float* tint = CGColorGetComponents( cgTint );
// - - -
int w = self.size.width;
int h = self.size.height;
int pixelCount = w * h;
uint8_t* data = [UIImage convertUIImageToBitmapRGBA8: self];
for( int i=0; i < pixelCount ; i++ )
{
int offset = i << 2; // same as 4 * i but faster
float in_r = data[ offset + R ];
float in_g = data[ offset + G ];
float in_b = data[ offset + B ];
// float in_a = data[ offset + A ];
if( i == 0 )
printf( "ALPHA %d ", data[ offset + A ] ); // corner pixel has alpha 0
float greyscale = 0.30 * in_r + 0.59 * in_g + 0.11 * in_b;
data[ offset + R ] = (uint8_t) ( greyscale * tint[ R ] );
data[ offset + G ] = (uint8_t) ( greyscale * tint[ G ] );
data[ offset + B ] = (uint8_t) ( greyscale * tint[ B ] );
}
UIImage* imageNew = [UIImage convertBitmapRGBA8ToUIImage: data
withWidth: w
withHeight: h ];
free( data );
// test corner pixel
{
uint8_t* test = [UIImage convertUIImageToBitmapRGBA8: self];
for( int i=0; i < 1 ; i++ )
{
int offset = i << 2;
// float in_r = test[ offset + R ];
// float in_g = test[ offset + G ];
// float in_b = test[ offset + B ];
// float in_a = data[ offset + A ];
printf( "ALPHA %d ", test[ offset + A ] ); // corner pixel still has alpha 0
}
free( test );
}
return imageNew;
}
El problema es que no recupero el canal alfa, lo está configurando opaco en todas partes.
Si simplemente transfiero la imagen de origen a la primera línea, se muestra correctamente, por lo que el problema no está en la imagen de origen.
Si inspecciono el componente alfa del primer píxel, me parece que es 0 (es decir, transparente) en todos los puntos del proceso, como debería ser. Incluso puedo hacer una prueba extra como puede ver: una vez que tengo mi último UIImage, lo vuelvo a romper en un mapa de bits RGBA e inspecciono el mismo elemento. Todavía es 0.
Entonces parece que debe haber algún error en el método convertUIImageToBitmapRGBA8. parece que debe haber algún ajuste en el UIImage resultante que lo hace pensar que es opaco en todas partes.
Pero mirando a través del código fuente de este método ( https://github.com/PaulSolt/UIImage-Conversion/blob/master/ImageHelper.m - toda la biblioteca es solo este archivo con su encabezado) No puedo ver dónde está el problema puede ser.
Este es el resultado de renderizado:
Como puede ver, la C se representa antes que la G antes de la F, por lo tanto, está recortada en ambos lados por los rectángulos.
Intento usar esa biblioteca, pero en la imagen de copia en lugar del canal alfa correcto recibo un desastre. imagen rota
Código:
UIImage *c = [UIImage imageNamed:@"head_diamond_c.png"];
unsigned char * rawData = [ImageHelper convertUIImageToBitmapRGBA8: c];
UIImage *copy = [ImageHelper convertBitmapRGBA8ToUIImage: rawData withWidth:c.size.width withHeight:c.size.height];
free(rawData);
itemImageView setImage:copy];