ios – 如何自动裁剪UIImage?

我有一个UI Image包含一个形状;其余的是透明的.我想要通过尽可能多的透明部分来获得另一个UIImage,仍然保留所有不透明像素 – 类似于GIMP中的自动裁剪功能.我该怎么做呢?

解决方法

这种方法可能比你希望的更有侵略性,但是它完成了工作.我正在做的是为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获得了一点代码.希望它有帮助!

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...