Одним из очень простых подходов является использование массива декодирования CGImageRef, но это может помочь только для отображения диапазона (без гаммы и т. Д.)
const CGFloat decode[6] = {blackPoint,whitePoint,blackPoint,whitePoint,blackPoint,whitePoint};
decodedImage = CGImageCreate(CGImageGetWidth(origImage),
CGImageGetHeight(origImage),
CGImageGetBitsPerComponent(origImage),
CGImageGetBitsPerPixel(origImage),
CGImageGetBytesPerRow(origImage),
CGImageGetColorSpace(origImage),
CGImageGetBitmapInfo(origImage),
CGImageGetDataProvider(origImage),
decode,
YES,
CGImageGetRenderingIntent(origImage)
);
Где whitePoint - это число с плавающей точкой от 0,0 до 1,0, которое определяет, какая яркость будет отображаться на чистый белый цвет в выходных данных, а blackPoint также является плавающей точкой, которая определяет, какая яркость отображается на чистый черный.
Элементы массива декодирования соответствуют компонентам цветового пространства, поэтому этот код будет работать только для изображений RBG. Вы можете установить для компонентов разные значения белого и черного, чтобы создать простую коррекцию цвета.
Вы можете рассчитать whitePoint и blackPoint с помощью следующей функции (без коррекции цвета):
void CalculateAutocorretionValues(CGImageRef image, CGFloat *whitePoint, CGFloat *blackPoint) {
UInt8* imageData = malloc(100 * 100 * 4);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef ctx = CGBitmapContextCreate(imageData, 100, 100, 8, 4 * 100, colorSpace, kCGImageAlphaNoneSkipLast);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(ctx, CGRectMake(0, 0, 100, 100), image);
int histogramm[256];
bzero(histogramm, 256 * sizeof(int));
for (int i = 0; i < 100 * 100 * 4; i += 4) {
UInt8 value = (imageData[i] + imageData[i+1] + imageData[i+2]) / 3;
histogramm[value]++;
}
CGContextRelease(ctx);
free(imageData);
int black = 0;
int counter = 0;
// count up to 200 (2%) values from the black side of the histogramm to find the black point
while ((counter < 200) && (black < 256)) {
counter += histogramm[black];
black ++;
}
int white = 255;
counter = 0;
// count up to 200 (2%) values from the white side of the histogramm to find the white point
while ((counter < 200) && (white > 0)) {
counter += histogramm[white];
white --;
}
*blackPoint = 0.0 - (black / 256.0);
*whitePoint = 1.0 + ((255-white) / 256.0);
}