iOS:如何将图像修剪成有用的部分(删除透明边框)

iOS:如何将图像修剪成有用的部分(删除透明边框),ios,uiimageview,uiimage,transparency,Ios,Uiimageview,Uiimage,Transparency,我试图在iPhone应用程序中自动显示基本透明的png的有用部分。图像可能是500x500,但大部分是透明的。图像中的某个地方有一个不透明的部分,我想向用户显示尽可能大的部分,所以我想从每一面尽可能多地修剪(或者通过在UIImageView中拉伸和移动使其看起来像那样。有什么想法吗?使用Quartz将图像转换为位图,检查alpha通道位以找到图像不透明部分的边界 以下是苹果技术说明:。您可以通过以下方式从UIImage获取CIImage: CGImageRef imageRef = [uiIma

我试图在iPhone应用程序中自动显示基本透明的png的有用部分。图像可能是500x500,但大部分是透明的。图像中的某个地方有一个不透明的部分,我想向用户显示尽可能大的部分,所以我想从每一面尽可能多地修剪(或者通过在UIImageView中拉伸和移动使其看起来像那样。有什么想法吗?

使用Quartz将图像转换为位图,检查alpha通道位以找到图像不透明部分的边界

以下是苹果技术说明:。您可以通过以下方式从UIImage获取CIImage:

CGImageRef imageRef = [uiImage CGImage];

我提出了一种方法,扫描图像中的所有像素,查找所有透明(0.01公差)的列或行与包含任何非透明像素的列或行,然后相应地修剪图像

///crops image by trimming transparent edges
-(UIImage *)trimImage:(UIImage *)originalImage {

    // components of replacement color – in a 255 UInt8 format (fairly standard bitmap format)
    const CGFloat* colorComponents = CGColorGetComponents([UIColor colorWithRed:1 green:0 blue:0 alpha:1].CGColor);
    UInt8* color255Components = calloc(sizeof(UInt8), 4);
    for (int i = 0; i < 4; i++) color255Components[i] = (UInt8)round(colorComponents[i]*255.0);

    // raw image reference
    CGImageRef rawImage = originalImage.CGImage;

    // image attributes
    size_t width = CGImageGetWidth(rawImage);
    size_t height = CGImageGetHeight(rawImage);
    CGRect rect = {CGPointZero, {width, height}};

    // image format
    size_t bitsPerComponent = 8;
    size_t bytesPerRow = width*4;

    // the bitmap info
    CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;

    // data pointer – stores an array of the pixel components. For example (r0, b0, g0, a0, r1, g1, b1, a1 .... rn, gn, bn, an)
    UInt8* data = calloc(bytesPerRow, height);

    // get new RGB color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    // create bitmap context
    CGContextRef ctx = CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);

    // draw image into context (populating the data array while doing so)
    CGContextDrawImage(ctx, rect, rawImage);

    //float iln2 = 1.0f/log(2.0f);

    float topTrim = 0;
    float bottomTrim = 0;
    float leftTrim = 0;
    float rightTrim = 0;

    @autoreleasepool {

        int pixelPosition = 0;

        //

        float row = 1;
        float column = 1;
        BOOL found = NO;
        while (row < height) {
            while (column < width) {
                pixelPosition = row*width+column;
                NSInteger pixelIndex = 4*pixelPosition;
                float alphaValue = data[pixelIndex+3]/255.0f;
                if (alphaValue > 0.01f) {
                    found = YES;
                    break;
                }
                column++;
            }
            if (found) {
                break;
            }
            column = 1;
            row++;
        }
        topTrim = row;

        //

        row = height-1;
        column = 1;
        found = NO;
        while (row > 0) {
            while (column < width) {
                pixelPosition = row*width+column;
                NSInteger pixelIndex = 4*pixelPosition;
                float alphaValue = data[pixelIndex+3]/255.0f;
                if (alphaValue > 0.01f) {
                    found = YES;
                    break;
                }
                column++;
            }
            if (found) {
                break;
            }
            column = 1;
            row--;
        }
        bottomTrim = row;

        //

        row = 1;
        column = 1;
        found = NO;
        while (column < width) {
            while (row < height) {
                pixelPosition = row*width+column;
                NSInteger pixelIndex = 4*pixelPosition;
                float alphaValue = data[pixelIndex+3]/255.0f;
                if (alphaValue > 0.01f) {
                    found = YES;
                    break;
                }
                row++;
            }
            if (found) {
                break;
            }
            row = 1;
            column++;
        }
        leftTrim = column;

        //

        row = 1;
        column = width-1;
        found = NO;
        while (column > 0) {
            while (row < height) {
                pixelPosition = row*width+column;
                NSInteger pixelIndex = 4*pixelPosition;
                float alphaValue = data[pixelIndex+3]/255.0f;
                if (alphaValue > 0.01f) {
                    found = YES;
                    break;
                }
                row++;
            }
            if (found) {
                break;
            }
            row = 1;
            column--;
        }
        rightTrim = column;

    }

    // clean up
    free(color255Components);
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    free(data);

    //

    float trimWidth = rightTrim-leftTrim;
    float trimHeight = bottomTrim-topTrim;

    UIView *trimCanvas = [[UIView alloc] initWithFrame:CGRectMake(0, 0, trimWidth, trimHeight)];
    trimCanvas.backgroundColor = [UIColor clearColor];

    UIImageView *trimImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    trimImageView.image = originalImage;
    trimImageView.contentMode = UIViewContentModeScaleToFill;
    trimImageView.backgroundColor = [UIColor clearColor];

    [trimCanvas addSubview:trimImageView];

    //

    trimImageView.center = CGPointMake(trimImageView.center.x-leftTrim, trimImageView.center.y-topTrim);

    //

    CGRect __rect = [trimCanvas bounds];
    UIGraphicsBeginImageContextWithOptions(__rect.size, (NO), (originalImage.scale));
    CGContextRef __context = UIGraphicsGetCurrentContext();
    [trimCanvas.layer renderInContext:__context];
    UIImage *__image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //

    return __image;

}
///通过修剪透明边缘修剪图像
-(UIImage*)修剪图像:(UIImage*)原始图像{
//替换颜色组件–采用255 UInt8格式(相当标准的位图格式)
常量CGFloat*colorComponents=CGColorGetComponents([uicolorWithred:1绿色:0蓝色:0 alpha:1].CGColor);
UInt8*color255Components=calloc(sizeof(UInt8),4);
对于(int i=0;i<4;i++)Color255组件[i]=(UInt8)轮(colorComponents[i]*255.0);
//原始图像参考
CGImageRef rawImage=originalImage.CGImage;
//图像属性
size\u t width=CGImageGetWidth(rawImage);
大小\u t高度=CGImageGetHeight(rawImage);
CGRect rect={CGPointZero,{width,height};
//图像格式
大小\u t比特分量=8;
尺寸=宽度*4;
//位图信息
CGBitmapInfo bitmapInfo=KCGIMAGEAlphaPremultipledLast | kCGBitmapByteOrder32Big;
//数据指针–存储像素组件的数组。例如(r0、b0、g0、a0、r1、g1、b1、a1…rn、gn、bn、an)
UInt8*data=calloc(bytesPerRow,高度);
//获取新的RGB颜色空间
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
//创建位图上下文
CGContextRef ctx=CGBitmapContextCreate(数据、宽度、高度、bitsPerComponent、bytesPerRow、颜色空间、bitmapInfo);
//将图像绘制到上下文中(执行此操作时填充数据数组)
CGContextDrawImage(ctx、rect、rawImage);
//浮动iln2=1.0f/对数(2.0f);
浮动顶部修剪=0;
浮动底部修剪=0;
float leftTrim=0;
浮动右微调=0;
@自动释放池{
int像素位置=0;
//
浮动行=1;
浮柱=1;
BOOL-found=NO;
while(行<高度){
while(列<宽度){
像素位置=行*宽+列;
NSInteger像素索引=4*像素位置;
浮点字母值=数据[pixelIndex+3]/255.0f;
如果(字母值>0.01f){
发现=是;
打破
}
列++;
}
如果(找到){
打破
}
列=1;
行++;
}
topTrim=行;
//
行=高度-1;
列=1;
发现=否;
而(行>0){
while(列<宽度){
像素位置=行*宽+列;
NSInteger像素索引=4*像素位置;
浮点字母值=数据[pixelIndex+3]/255.0f;
如果(字母值>0.01f){
发现=是;
打破
}
列++;
}
如果(找到){
打破
}
列=1;
行--;
}
底部修剪=行;
//
行=1;
列=1;
发现=否;
while(列<宽度){
while(行<高度){
像素位置=行*宽+列;
NSInteger像素索引=4*像素位置;
浮点字母值=数据[pixelIndex+3]/255.0f;
如果(字母值>0.01f){
发现=是;
打破
}
行++;
}
如果(找到){
打破
}
行=1;
列++;
}
leftTrim=列;
//
行=1;
列=宽度-1;
发现=否;
而(列>0){
while(行<高度){
像素位置=行*宽+列;
NSInteger像素索引=4*像素位置;
浮点字母值=数据[pixelIndex+3]/255.0f;
如果(字母值>0.01f){
发现=是;
打破
}
行++;
}
如果(找到){
打破
}
行=1;
列--;
}
rightTrim=列;
}
//清理
免费(255种成分);
CGContextRelease(ctx);
CGCOLORSPACTERELEASE(色彩空间);
免费(数据);
//
浮动修剪宽度=右修剪左修剪;
浮动修剪高度=底部修剪顶部修剪;
UIView*trimCanvas=[[UIView alloc]initWithFrame:CGRectMake(0,0,trimWidth,trimHeight)];
trimCanvas.backgroundColor=[UIColor clearColor];
UIImageView*trimImageView=[[UIImageView alloc]initWithFrame:CGRectMake(0,0,宽度,高度)];
trimImageView.image=原始图像;
trimImageView.contentMode=UIViewContentModeScaleToFill;
trimImageView.backgroundColor=[UIColor clearColor];
[trimCanvas添加子视图:trimImageView];
//
trimImageView.center=CGPointMake(trimImageView.center.x-leftTrim,trimImageView.center.y-topTrim);
//
CGRect uu rect=[trimCanvas界限];
UIGraphicsBeginImageContextWithOptions(u_rect.size,(NO),(originalImage.scale));
CGContextRef_u_context=UIGraphicsGetCurrentContext();
[trimCan