我有一张灰度图像,我在图像的某些部分应用它的原始颜色,我已经实现了它。现在我想改变我在图像中应用原始颜色的部分的颜色
我有这个: Original Image
我想转换成: Result Image
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
NSUInteger bytesCount = height * width * bytesPerPixel;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char *)calloc(bytesCount, sizeof(unsigned char));
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
unsigned char *outputData = (unsigned char *)calloc(bytesCount, sizeof(unsigned char));
NSUInteger byteIndex = 0;
for (NSUInteger i=0; i<bytesCount / bytesPerPixel; ++i) {
CGFloat red = (CGFloat)rawData[byteIndex];
CGFloat green = (CGFloat)rawData[byteIndex+1];
CGFloat blue = (CGFloat)rawData[byteIndex+2];
CGFloat alpha = (CGFloat)rawData[byteIndex+3];
BOOL grayscale = red == green == blue;
if (!grayscale) {
// test for near values
CGFloat diff = MAX(ABS(red-green), MAX(ABS(red-blue), ABS(green-blue)));
static CGFloat allowedDifference = 100; // in range of 0-255
if (diff > allowedDifference) {
// CGFloat redTemp = 236;
// red = green;
// green = redTemp;
red = 236.0;
green = 17.0;
blue = 17.0;
}
}
outputData[byteIndex] = red;
outputData[byteIndex+1] = green;
outputData[byteIndex+2] = blue;
outputData[byteIndex+3] = alpha;
byteIndex += bytesPerPixel;
}
free(rawData);
CGDataProviderRef outputDataProvider = CGDataProviderCreateWithData(NULL,
outputData,
bytesCount,
NULL);
free(outputData);
CGImageRef outputImageRef = CGImageCreate(width,
height,
bitsPerComponent,
bytesPerPixel * 8,
bytesPerRow,
colorSpace,
kCGBitmapByteOrderDefault,
outputDataProvider,
NULL,NO,
kCGRenderingIntentDefault);
CGColorSpaceRelease(colorSpace);
CGDataProviderRelease(outputDataProvider);
UIImage *outputImage = [UIImage imageWithCGImage:outputImageRef];
CGImageRelease(outputImageRef);
我尝试了bitmapcontext
和所有内容,但没有得到理想的结果。
有人有想法吗?
答案 0 :(得分:1)
您可以尝试使用CGBitmapContextCreate从图像抓取像素数据来创建颜色空间,然后通过CGContextDrawImage将图像绘制到它。
其次,您将收到一个维度的字节数组。 像这样:[r1,g1,b1,a1,r2,g2,b2,a2,...]其中r,g,b,a - 颜色成分,1,2 - nu。像素。
在此之后,您可以迭代数组并比较每个像素的颜色分量。由于你应该跳过灰度像素,你需要比较rgb参数,理论上它们必须相等,但你也可以支持几个数字的一些小错误+ - 。
如果具体像素不是灰度,只需交换红色和绿色字节。
应该是要走的路。
更新了示例:
UIImage *image = [UIImage imageNamed:@"qfjsc.png"];
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
NSUInteger bytesCount = height * width * bytesPerPixel;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = (unsigned char *)calloc(bytesCount, sizeof(unsigned char));
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
unsigned char *outputData = (unsigned char *)calloc(bytesCount, sizeof(unsigned char));
NSUInteger byteIndex = 0;
for (NSUInteger i=0; i<bytesCount / bytesPerPixel; ++i) {
CGFloat red = (CGFloat)rawData[byteIndex];
CGFloat green = (CGFloat)rawData[byteIndex+1];
CGFloat blue = (CGFloat)rawData[byteIndex+2];
CGFloat alpha = (CGFloat)rawData[byteIndex+3];
BOOL grayscale = red == green == blue;
if (!grayscale) {
// test for near values
CGFloat diff = MAX(ABS(red-green), MAX(ABS(red-blue), ABS(green-blue)));
static CGFloat allowedDifference = 50.0; // in range of 0-255
if (diff > allowedDifference) {
CGFloat redTemp = red;
red = green;
green = redTemp;
}
}
outputData[byteIndex] = red;
outputData[byteIndex+1] = green;
outputData[byteIndex+2] = blue;
outputData[byteIndex+3] = alpha;
byteIndex += bytesPerPixel;
}
free(rawData);
CGDataProviderRef outputDataProvider = CGDataProviderCreateWithData(NULL,
outputData,
bytesCount,
NULL);
free(outputData);
CGImageRef outputImageRef = CGImageCreate(width,
height,
bitsPerComponent,
bytesPerPixel * 8,
bytesPerRow,
colorSpace,
kCGBitmapByteOrderDefault,
outputDataProvider,
NULL,NO,
kCGRenderingIntentDefault);
CGColorSpaceRelease(colorSpace);
CGDataProviderRelease(outputDataProvider);
UIImage *outputImage = [UIImage imageWithCGImage:outputImageRef];
CGImageRelease(outputImageRef);
请注意静态允许的差异变量。它允许您跳过几乎非灰度像素,但它们在RGB色彩空间中并且本质上几乎是灰度级。
以下是示例: