解决方法
这种方法可能比你希望的更有侵略性,但是它完成了工作.我正在做的是为UIImage创建一个位图上下文,获取一个指向原始图像数据的指针,然后筛选它来查找非透明像素.我的方法返回一个CGRect,我用来创建一个新的UIImage.
- (CGRect)cropRectForImage:(UIImage *)image { CGImageRef cgImage = image.CGImage; CGContextRef context = [self createARGBBitmapContextFromImage:cgImage]; if (context == NULL) return CGRectZero; size_t width = CGImageGetWidth(cgImage); size_t height = CGImageGetHeight(cgImage); CGRect rect = CGRectMake(0,width,height); CGContextDrawImage(context,rect,cgImage); unsigned char *data = CGBitmapContextGetData(context); CGContextRelease(context); //Filter through data and look for non-transparent pixels. int lowX = width; int lowY = height; int highX = 0; int highY = 0; if (data != NULL) { for (int y=0; y<height; y++) { for (int x=0; x<width; x++) { int pixelIndex = (width * y + x) * 4 /* 4 for A,R,G,B */; if (data[pixelIndex] != 0) { //Alpha value is not zero; pixel is not transparent. if (x < lowX) lowX = x; if (x > highX) highX = x; if (y < lowY) lowY = y; if (y > highY) highY = y; } } } free(data); } else { return CGRectZero; } return CGRectMake(lowX,lowY,highX-lowX,highY-lowY); }
创建位图上下文的方法:
- (CGContextRef)createARGBBitmapContextFromImage:(CGImageRef)inImage { CGContextRef context = NULL; CGColorSpaceRef colorSpace; void *bitmapData; int bitmapByteCount; int bitmapBytesPerRow; // Get image width,height. We'll use the entire image. size_t width = CGImageGetWidth(inImage); size_t height = CGImageGetHeight(inImage); // Declare the number of bytes per row. Each pixel in the bitmap in this // example is represented by 4 bytes; 8 bits each of red,green,blue,and // alpha. bitmapBytesPerRow = (width * 4); bitmapByteCount = (bitmapBytesPerRow * height); // Use the generic RGB color space. colorSpace = CGColorSpaceCreateDeviceRGB(); if (colorSpace == NULL) return NULL; // Allocate memory for image data. This is the destination in memory // where any drawing to the bitmap context will be rendered. bitmapData = malloc( bitmapByteCount ); if (bitmapData == NULL) { CGColorSpaceRelease(colorSpace); return NULL; } // Create the bitmap context. We want pre-multiplied ARGB,8-bits // per component. Regardless of what the source image format is // (CMYK,Grayscale,and so on) it will be converted over to the format // specified here by CGBitmapContextCreate. context = CGBitmapContextCreate (bitmapData,height,8,// bits per component bitmapBytesPerRow,colorSpace,kCGImageAlphaPremultipliedFirst); if (context == NULL) free (bitmapData); // Make sure and release colorspace before returning CGColorSpaceRelease(colorSpace); return context; }
最后,从返回的CGRect中获得新的UIImage:
CGRect newRect = [self cropRectForImage:oldImage]; CGImageRef imageRef = CGImageCreateWithImageInRect(oldImage.CGImage,newRect); UIImage *newImage = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef);
我从this very useful article获得了一点代码.希望它有帮助!