知识点:iOS/Mac去掉截图Alpha通道

2,589 阅读1分钟

在项目开发过程中,遇到一种很奇怪的现象:同一张图片,在iOS、Mac端能很正常的显示出来,但在H5、Android端却显示不出来。经过对比正常的图片与这张异常图片,发现区别在于异常图片Alpha通道一项的值为“是”,而正常能够显示出来的图片该值为“否”。查看图片简介如下:

那么怎么去掉一张截图的Alpha通道呢?

1. 方法一

-(void)converter:(NSString*)name{
    
    NSLog(@"NAME: %@",name);

    NSURL *url = [NSURL fileURLWithPath:name];
    CGImageSourceRef source;
    NSImage *srcImage =[[NSImage alloc] initWithContentsOfURL:url];;
    NSLog(@"URL: %@",url);
    source = CGImageSourceCreateWithData((__bridge CFDataRef)[srcImage TIFFRepresentation], NULL);
    CGImageRef imageRef =  CGImageSourceCreateImageAtIndex(source, 0, NULL);
    CGRect rect = CGRectMake(0.f, 0.f, CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL,
                                                       rect.size.width,
                                                       rect.size.height,
                                                       CGImageGetBitsPerComponent(imageRef),
                                                       CGImageGetBytesPerRow(imageRef),
                                                       CGImageGetColorSpace(imageRef),
                                                       kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Little
                                                       );
    
    CGContextDrawImage(bitmapContext, rect, imageRef);
    
    CGImageRef decompressedImageRef = CGBitmapContextCreateImage(bitmapContext);
    
    NSImage *finalImage = [[NSImage alloc] initWithCGImage:decompressedImageRef size:NSZeroSize];
    NSData *imageData = [finalImage  TIFFRepresentation];
    NSBitmapImageRep *imageRep = [NSBitmapImageRep imageRepWithData:imageData];
    NSDictionary *imageProps = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:0.9] forKey:NSImageCompressionFactor];
    imageData = [imageRep representationUsingType:NSPNGFileType properties:imageProps];
    [imageData writeToFile:name atomically:NO];
    
    CGImageRelease(decompressedImageRef);
    CGContextRelease(bitmapContext);
}

2. 方法二

CGImageRef imageRef = [image CGImageForProposedRect:&((CGRect){0,0,image.size.width,image.size.height}) context:nil hints:nil];
NSInteger bytesPerRow = CGImageGetBytesPerRow(imageRef);
NSInteger bitsPerPixel = CGImageGetBitsPerPixel(imageRef);
NSInteger bitsPerSample = 16;
bool hasAlpha = NO;
NSInteger samplesPerPixel = hasAlpha ? 4 : 3;
///画布
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]
                             initWithBitmapDataPlanes:NULL
                             pixelsWide:image.size.width
                             pixelsHigh:image.size.height
                             bitsPerSample:bitsPerSample
                             samplesPerPixel:samplesPerPixel
                             hasAlpha:NO
                             isPlanar:NO
                             colorSpaceName:NSCalibratedRGBColorSpace
                             bytesPerRow:bytesPerRow*(bitsPerSample/8)
                             bitsPerPixel:bitsPerPixel*(bitsPerSample/8)];
NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithBitmapImageRep:rep];
    
[NSGraphicsContext setCurrentContext:context];
[image drawInRect:NSMakeRect(0, 0, image.size.width, image.size.height)  fromRect:NSZeroRect operation:NSCompositingOperationCopy fraction:1.0];
NSData *data = [rep representationUsingType:NSBitmapImageFileTypePNG properties:@{}];
NSImage *resultImage = [[NSImage alloc]initWithData:data];

方法不一样,思路一致,可以根据自己的需求调整参数。输出结果后,再次打开图片简介查看Alpha通道值。