简体   繁体   English

iOS灰度/黑白

[英]iOS grayscale/black & white

I am having an issue with some code that changes a UIImage to grayscale. 我遇到一些将UIImage更改为灰度的代码的问题。 It works right on iPhone/iPod, but on iPad whatever is already drawn gets all stretched and skewed in the process. 它可以在iPhone / iPod上正常运行,但在iPad上,任何已绘制的内容都会在此过程中拉伸和倾斜。

It also sometimes crashes only on iPad on the line imageRef = CGBitmapContextCreateImage (ctx); 有时也仅在iPad上的imageRef = CGBitmapContextCreateImage(ctx)行上崩溃;

Here is the code: 这是代码:

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);

Consider leveraging the CIColorMonochrome filter available in iOS 6. 考虑利用iOS 6中提供的CIColorMonochrome滤镜。

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;
}

Figured it out with some help elsewhere 在其他地方找到帮助

Got rid of an extra context being used and changed the bitmap format 摆脱了使用额外的上下文并更改了位图格式

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM