I am dealing with an iphone application which would choose a specific colored pixel from the image and replace it with some other color shades i choose from color menu. Problem is that the code i have implemented is working fine on simulator, but when i run the same code on device all i get is that, the image's pixels are replaced by only white color. I am pasting the code below, If any one has clue like how to implement it then it would be great help
// This is data buffer details of whole image's pixels
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,bitsPerComponent, bytesPerRow, colorSpace,kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
//Second image into buffer
//This is data buffer of the pixel to be replaced that i am selecting from image
CGImageRef imageRefs = [selectedColorImage.image CGImage];
NSUInteger widths = CGImageGetWidth(imageRefs);
NSUInteger heights = CGImageGetHeight(imageRefs);
CGColorSpaceRef colorSpaces = CGColorSpaceCreateDeviceRGB();
unsigned char *rawDatas = malloc(heights * widths * 4);
NSUInteger bytesPerPixels = 4;
NSUInteger bytesPerRows = bytesPerPixels * widths;
NSUInteger bitsPerComponents = 8;
CGContextRef contexts = CGBitmapContextCreate(rawDatas, widths, heights,bitsPerComponents, bytesPerRows, colorSpaces,kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpaces);
CGContextDrawImage(contexts, CGRectMake(0, 0, widths, heights), imageRefs);
CGContextRelease(contexts);
// Now your rawData contains the image data in the RGBA8888 pixel format.
int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel;
int byteIndexs = (bytesPerRows * 0) + 0 * bytesPerPixels;
int i=0;
for (int ii = 0 ; ii < count ; ++ii)
{
CGFloat redb = (rawData[byteIndex] * 1.0) / 255.0;
CGFloat greenb = (rawData[byteIndex + 1] * 1.0) / 255.0;
CGFloat blueb = (rawData[byteIndex + 2] * 1.0) / 255.0;
CGFloat alphab = (rawData[byteIndex + 3] * 1.0) / 255.0;
CGFloat reds = (rawDatas[byteIndexs] * 1.0) / 255.0;
CGFloat greens = (rawDatas[byteIndexs + 1] * 1.0) / 255.0;
CGFloat blues = (rawDatas[byteIndexs + 2] * 1.0) / 255.0;
CGFloat alphas = (rawDatas[byteIndexs + 3] * 1.0) / 255.0;
/* CGColorRef ref=[[shapeButton backgroundColor] CGColor];
switch(CGColorSpaceGetModel(CGColorGetColorSpace(ref)))
{
case kCGColorSpaceModelMonochrome:
// For grayscale colors, the luminance is the color value
//luminance = components[0];
break;
case kCGColorSpaceModelRGB:
// For RGB colors, we calculate luminance assuming sRGB Primaries as per
// http://en.wikipedia.org/wiki/Luminance_(relative)
//luminance = 0.2126 * components[0] + 0.7152 * components[1] + 0.0722 * components[2];
break;
case kCGColorSpaceModelCMYK:
case kCGColorSpaceModelLab:
case kCGColorSpaceModelDeviceN:
case kCGColorSpaceModelIndexed:
break;
case kCGColorSpaceModelUnknown:
break;
case kCGColorSpaceModelPattern:
break;
//default:
// We don't implement support for non-gray, non-rgb colors at this time.
// Since our only consumer is colorSortByLuminance, we return a larger than normal
// value to ensure that these types of colors are sorted to the end of the list.
//luminance = 2.0;
}
int numComponents = CGColorGetNumberOfComponents(ref);
if (numComponents == 4)
{
const CGFloat *components = CGColorGetComponents(ref);
CGFloat red = components[0];
CGFloat green = components[1];
CGFloat blue = components[2];
CGFloat alpha = components[3];
}*/
if((redb==red/255.0f)&&(greenb=green/255.0f)&&(blueb=blue/255.0f)&&(alphab==alpha/255.0f))
{
if(button_tag ==1)
{
NSLog(@"color matching %d",i);//done
i++;
rawData[byteIndex]=(reds*255.0)/1.0+999999999;
rawData[byteIndex+1]=(blues*255.0)/1.0+000000800.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+999999000.0;
rawData[byteIndex+3]=(alphas*255.0)/255.0;
}
if(button_tag ==2)
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+899989989;
rawData[byteIndex+1]=(blues*255.0)/1.0+898998999.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+899989900.0;
rawData[byteIndex+3]=(alphas*255.0)/255.0;
}
if(button_tag ==3)
{
NSLog(@"color matching %d",i);//done
i++;
rawData[byteIndex]=(reds*255.0)/1.0+999999999;
rawData[byteIndex+1]=(blues*255.0)/1.0+990000800.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+999999000.0;
rawData[byteIndex+3]=(alphas*255.0)/10.0;
}
if(button_tag ==4)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+50.0;
rawData[byteIndex+1]=(blues*255.0)/1.0+50.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+50.0;
rawData[byteIndex+3]=(alphas*0.0)/0.0;
}
if(button_tag ==5)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+255000000.0;
rawData[byteIndex+1]=(blues*255.0)/1.0+000000000.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+000000255.0;
rawData[byteIndex+3]=(alphas*255.0)/10.0;
}
if(button_tag ==6)// done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+0.0;
rawData[byteIndex+1]=(blues*255.0)/1.0+1.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+0.0;
rawData[byteIndex+3]=(alphas*255.0)/0.0;
}
if(button_tag ==7)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+255255255.0f;
rawData[byteIndex+1]=(blues*255.0)/1.0+000255255.0f;
rawData[byteIndex+2]=(greens*255.0)/1.0+255255255.0f;
rawData[byteIndex+3]=(alphas*255.0)/255.0;
}
if(button_tag ==8)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+200.0;
rawData[byteIndex+1]=(blues*255.0)/1.0+200.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+200.0;
rawData[byteIndex+3]=(alphas*0.0)/0.0;
}
if(button_tag ==9)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+1.0;
rawData[byteIndex+1]=(blues*255.0)/1.0+0.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+0.0;
rawData[byteIndex+3]=(alphas*255.0)/0.0;
}
if(button_tag ==10)//done
{
i++;
rawData[byteIndex]=(reds*255.0)/1.0+999999999;
rawData[byteIndex+1]=(blues*255.0)/1.0+990000888.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+999999000.0;
rawData[byteIndex+3]=(alphas*255.0)/10.0;
}
if(button_tag ==11)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+900000000;
rawData[byteIndex+1]=(blues*255.0)/1.0+990000800.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+999999000.0;
rawData[byteIndex+3]=(alphas*255.0)/255.0;
}
if(button_tag ==12)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+150.0f;
rawData[byteIndex+1]=(blues*255.0)/1.0+150.0f;
rawData[byteIndex+2]=(greens*255.0)/1.0+150.0f;
rawData[byteIndex+3]=(alphas*255.0)/255.0f;
}
if(button_tag ==13)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+0.0;
rawData[byteIndex+1]=(blues*255.0)/1.0+0.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+0.0;
rawData[byteIndex+3]=(alphas*255.0)/0.0;
}
if(button_tag ==14)//done
{
NSLog(@"color matching %d",i);
i++;
rawData[byteIndex]=(reds*255.0)/1.0+10.0;
rawData[byteIndex+1]=(blues*255.0)/1.0+10.0;
rawData[byteIndex+2]=(greens*255.0)/1.0+10.0;
rawData[byteIndex+3]=(alphas*255.0)/1.0;
}
}
byteIndex += 4;
//byteIndexs += 4;
}
CGSize size=CGSizeMake(320, 330);
UIImage *newImage= [self imageWithBits:rawData withSize:size];
[backgroundImage setImage:newImage];
[self Hide开发者_如何学CLoadingIndicator];
//free(rawData);
//free(rawDatas);
Thanks in advance :)
While I can't tell you exactly what your problem is, I'm noticing a lot of code similar to:
rawData[byteIndex]=(reds*255.0)/1.0+999999999;
which when writing to a single byte is going to max out the value (255). Doing that four times over an RGBA8 pixel will render it white and opaque.
Comparing floats will always be inexact. Use the original integer values instead; they are easier to work with and will be quicker.
edit: something similar to this should work to replace white with transparent:
uint32_t *pixels = (pointer to image data);
uint32_t sourceColor = 0xffffffff;
uint32_t destColor = 0x00000000;
size_t pixelCount = width * height;
for (int i = 0; i < pixelCount; i++)
if (pixels[i] == sourceColor)
pixels[i] = destColor;
精彩评论