像素颜色替换在模拟器上工作正常,但在 iPhone 上不行

发布于 2024-08-23 10:21:34 字数 9949 浏览 6 评论 0原文

我正在处理一个 iPhone 应用程序,它会从图像中选择特定的彩色像素,并将其替换为我从颜色菜单中选择的其他色调。问题是我实现的代码在模拟器上运行良好,但是当我在设备上运行相同的代码时,我得到的只是图像的像素仅被白色替换。我粘贴下面的代码,如果有人知道如何实现它,那么这将是很大的帮助,

 // 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 HideLoadingIndicator];

//free(rawData);
//free(rawDatas);

提前致谢:)

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 HideLoadingIndicator];

//free(rawData);
//free(rawDatas);

Thanks in advance :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

走野 2024-08-30 10:21:34

虽然我无法确切地告诉您您的问题是什么,但我注意到很多类似于以下内容的代码:

rawData[byteIndex]=(reds*255.0)/1.0+999999999;

当写入单个字节时,该代码将最大化该值(255)。对 RGBA8 像素执行四次将使其变为白色且不透明。

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.

天赋异禀 2024-08-30 10:21:34

比较浮点数总是不准确的。使用原始整数值代替;他们更容易合作并且速度更快。

编辑:与此类似的东西应该可以用透明替换白色:

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;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文