ios - pecas - Imagen principal El filtro de brillo de CIColorControls crea un efecto incorrecto. ¿Cómo cambio la luminancia de mi imagen?
app para poner pecas en las fotos (3)
También encontré que la no linealidad de kCIInputBrightnessKey
de CIColorControls
es molesta. CIToneCurve
un CIToneCurve
lineal:
/** Change luminosity of `CIImage`
@param inputImage The `CIImage` of the image to have it''s luminosity changed.
@param luminosity The percent change of the luminosity, ranging from -1.0 to 1.0.
@return `CIImage` of image with luminosity changed. If luminosity of 0.0 used, original `inputImage` is returned.
*/
- (CIImage *)changeLuminosityOfCIImage:(CIImage *)inputImage luminosity:(CGFloat)luminosity
{
if (luminosity == 0)
return inputImage;
NSParameterAssert(luminosity >= -1.0 && luminosity <= 1.0);
CIFilter *toneCurveFilter = [CIFilter filterWithName:@"CIToneCurve"];
[toneCurveFilter setDefaults];
[toneCurveFilter setValue:inputImage forKey:kCIInputImageKey];
if (luminosity > 0)
{
[toneCurveFilter setValue:[CIVector vectorWithX:0.0 Y:luminosity] forKey:@"inputPoint0"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.25 Y:luminosity + 0.25 * (1 - luminosity)] forKey:@"inputPoint1"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.50 Y:luminosity + 0.50 * (1 - luminosity)] forKey:@"inputPoint2"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.75 Y:luminosity + 0.75 * (1 - luminosity)] forKey:@"inputPoint3"];
[toneCurveFilter setValue:[CIVector vectorWithX:1.0 Y:1.0] forKey:@"inputPoint4"];
}
else
{
[toneCurveFilter setValue:[CIVector vectorWithX:0.0 Y:0.0] forKey:@"inputPoint0"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.25 Y:0.25 * (1 + luminosity)] forKey:@"inputPoint1"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.50 Y:0.50 * (1 + luminosity)] forKey:@"inputPoint2"];
[toneCurveFilter setValue:[CIVector vectorWithX:0.75 Y:0.75 * (1 + luminosity)] forKey:@"inputPoint3"];
[toneCurveFilter setValue:[CIVector vectorWithX:1.0 Y:1 + luminosity] forKey:@"inputPoint4"];
}
return [toneCurveFilter outputImage];
}
Aquí está su imagen, reduciendo la luminosidad en un 30% usando la rutina anterior:
Se puede hacer con CIToneCurve
. Ya sea más rápido que tu rutina, tendrás un punto de referencia.
Estoy creando un selector de color para iOS. Me gustaría permitir al usuario seleccionar el brillo (luminancia) y hacer que la rueda de colores refleje este cambio. Estoy usando Core Image para modificar el brillo con el filtro CIColorControls. Aquí está mi código:
-(CIImage *)oldPhoto:(CIImage *)img withBrightness:(float)intensity
{
CIFilter *lighten = [CIFilter filterWithName:@"CIColorControls"];
[lighten setValue:img forKey:kCIInputImageKey];
[lighten setValue:@((intensity * 2.0) - 1.0) forKey:@"inputBrightness"];
return lighten.outputImage;
}
Así es como se ve la rueda de colores con intensidad = 0.5 (inputBrightness = 0):
El problema es que la rueda de color se ve mal cuando la intensidad es <0.5. Por ejemplo, así es como se ve con intensidad = 0.3 (inputBrightness = -0.4):
Observe que hay un círculo negro en el medio y que el resto de la imagen tampoco se ha oscurecido correctamente. Se supone que es una rueda de color HSL, así que supongo que lo que realmente quiero cambiar es la luminancia, no el brillo.
Primero, ¿alguien puede explicar por qué la imagen se ve así? No soy un experto en color; parece extraño que el centro del círculo se recorta rápidamente en negro, mientras que los bordes no se oscurecen demasiado.
En segundo lugar, ¿cómo puedo lograr el efecto que quiero?
Así es como realmente QUIERO que se vea la imagen:
Esto se creó con una función HSL personalizada y luminancia = 0.3. Esto se ejecuta en la CPU, por lo que es demasiado lento para mis necesidades. Me gustaría publicar el código para esta función de HSL, pero no lo incluí porque no parecía relevante de inmediato. Si quieres verlo, solo pregunta.
Por favor, avíseme si tiene alguna pregunta o si algo no está claro. ¡Gracias!
Su filtro CIColorControls está funcionando como está diseñado. Simplemente agrega su parámetro de brillo a los valores rojo, verde y azul de cada píxel. Si un brillo negativo toma el píxel por debajo de 0, se recorta en negro. Si un brillo positivo lo empuja más de 1, se recorta en blanco. (En realidad, cada canal se graba por separado ...)
Otro problema es que CIColorControls funciona en el espacio de color RGB. HSL es muy diferente. Esta es la razón por la que su rueda de color base se ve muy diferente del selector de color estándar de Apple.
Pruebe esto y cambie el valor usando un deslizador: -
- (void)viewDidLoad{
UIImage *aUIImage = showPickedImageView.image;
CGImageRef aCGImage = aUIImage.CGImage;
aCIImage = [CIImage imageWithCGImage:aCGImage];
context = [[CIContext contextWithOptions:nil] retain];
brightnessFilter = [[CIFilter filterWithName:@"CIColorControls" keysAndValues: @"inputImage", aCIImage, nil] retain];
}
- (IBAction)brightnessSliderValueChanged:(id)sender {
[brightnessFilter setValue:[NSNumber numberWithFloat:brightnessSlider.value ] forKey: @"inputBrightness"];
outputImage = [brightnessFilter outputImage];
CGImageRef cgiig = [context createCGImage:outputImage fromRect:[outputImage extent]];
newUIImage = [UIImage imageWithCGImage:cgiig];
CGImageRelease(cgiig);
[showPickedImageView setImage:newUIImage];
}