2012-01-25 54 views
1

我遇到了一些将UIImage更改为灰度的代码问题。它可以在iPhone/iPod上正常工作,但在iPad上,任何已经绘制出来的东西都会在整个过程中出现拉伸和偏斜。iOS灰度/黑白

它也有时会崩溃只在iPad上线 imageRef = CGBitmapContextCreateImage(ctx);

下面是代码:

CGContextRef ctx; 
CGImageRef imageRef = [self.drawImage.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); 

int byteIndex = 0; 
int grayScale; 

for(int ii = 0 ; ii < width * height ; ++ii) 
{ 
    grayScale = (rawData[byteIndex] + rawData[byteIndex + 1] + rawData[byteIndex + 2])/3; 

    rawData[byteIndex] = (char)grayScale; 
    rawData[byteIndex+1] = (char)grayScale; 
    rawData[byteIndex+2] = (char)grayScale; 
    //rawData[byteIndex+3] = 255; 

    byteIndex += 4; 
} 


ctx = CGBitmapContextCreate(rawData, 
          CGImageGetWidth(imageRef), 
          CGImageGetHeight(imageRef), 
          8, 
          CGImageGetBytesPerRow(imageRef), 
          CGImageGetColorSpace(imageRef), 
          kCGImageAlphaPremultipliedLast); 

imageRef = CGBitmapContextCreateImage (ctx); 
UIImage* rawImage = [UIImage imageWithCGImage:imageRef]; 

CGContextRelease(ctx); 

self.drawImage.image = rawImage; 

free(rawData); 
+0

如果您在iPad上使用iPhone上使用的相同图像,会发生什么情况?我怀疑在图像格式或其他方面存在差异。此外,请注意,有一种更好的算法可以转换为将红色值的30%,绿色值的59%和蓝色值的11%相加的灰度级,如下所示:grayScale =((rawData [byteIndex] * 0.3f)+(rawData [byteIndex + 1] * 0.59)+(rawData [byteIndex + 2] * 0.11)); –

+0

图像格式每次都是一样的。你可以随心所欲地画画,然后点击灰度按钮。它只是倾斜在iPad上,并经常在imageRef = CGBitmapContextCreateImage(ctx)上崩溃;只在iPad上 –

回答

1

想通了一些帮助其他地方

摆脱了额外的上下文中使用,改变了位图格式

CGContextRef ctx; 
CGImageRef imageRef = [self.drawImage.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 = CGImageGetBitsPerComponent(imageRef); 

ctx = CGBitmapContextCreate(rawData, 
          width, 
          height, 
          bitsPerComponent, 
          bytesPerRow, 
          colorSpace, 
          kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); 

CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), imageRef); 

int byteIndex = 0; 
int grayScale; 

for(int ii = 0 ; ii < width * height ; ++ii) 
{ 
    grayScale = (rawData[byteIndex] + rawData[byteIndex + 1] + rawData[byteIndex + 2])/3; 

    rawData[byteIndex] = (char)grayScale; 
    rawData[byteIndex+1] = (char)grayScale; 
    rawData[byteIndex+2] = (char)grayScale; 
    //rawData[byteIndex+3] = 255; 

    byteIndex += 4; 
} 


imageRef = CGBitmapContextCreateImage(ctx); 
UIImage* rawImage = [UIImage imageWithCGImage:imageRef]; 

CGColorSpaceRelease(colorSpace); 
CGContextRelease(ctx); 

self.drawImage.image = rawImage; 

free(rawData); 
2

考虑借力CIColorMonochrome筛选在iOS 6中可用。

void ToMonochrome() 
{ 
    var mono = new CIColorMonochrome(); 
    mono.Color = CIColor.FromRgb(1, 1, 1); 
    mono.Intensity = 1.0f; 
    var uiImage = new UIImage("Images/photo.jpg"); 
    mono.Image = CIImage.FromCGImage(uiImage.CGImage); 
    DisplayFilterOutput(mono, ImageView); 
} 

static void DisplayFilterOutput(CIFilter filter, UIImageView imageView) 
{ 
    CIImage output = filter.OutputImage; 
    if (output == null) 
     return; 
    var context = CIContext.FromOptions(null); 
    var renderedImage = context.CreateCGImage(output, output.Extent); 
    var finalImage = new UIImage(renderedImage); 
    imageView.Image = finalImage; 
}