修剪UIImage边框

时间:2013-11-18 20:10:14

标签: ios objective-c c uiimage cgimage

以下是我想修剪的图片示例。我想摆脱图像周围的边框(在这种情况下是顶部和底部黑条)。

UIImage to trim

我在Github上找到了一个库:CKImageAdditions,但它似乎不起作用。当我传入UIColor(RGB颜色)时,它只返回相同的图像。

我可以找到许多示例和类别类来修剪UIImage,任何透明像素作为边框,但在这种情况下我需要修剪黑色。我在我的图像中对颜色进行了采样,颜色值确实为255,但它似乎与上面的库所需的颜色不匹配。

是否有人拥有他们使用的图书馆或任何见解?我进行了搜索和搜索,CKImageAdditions是我唯一可以找到广告用颜色修剪的东西(虽然不幸的是在我的情况下不起作用)。

2 个答案:

答案 0 :(得分:7)

我最终定义了function in CKImageAdditions中具有此功能的方法,但我无法使其工作。它只是不会修剪颜色,所以我改为检查像素的RGB值为\0(黑色)。不幸的是,CKImageAdditions无法找到黑色像素。

由于我想修剪的图像有时没有超级黑条(有时它们会有一个较暗的颜色的杂散像素或其他东西)我在方法中添加了GPUImage功能,基本上只是创建一个黑白版本的图像,上面有一个强大的滤镜,所以任何深色都会变成黑色,任何浅色变成白色,使得黑条边框更加突出,并且当我在方法中查找它们时确保更好的效果。当然,我会根据黑/白图像的结果在最后裁剪原始图像。

这是我的代码:

typedef struct Pixel { uint8_t r, g, b, a; } Pixel;

+(UIImage*)trimBlack:(UIImage*)originalImage {
    GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:originalImage];
    GPUImageLuminanceThresholdFilter *stillImageFilter = [[GPUImageLuminanceThresholdFilter alloc] init];
    stillImageFilter.threshold = 0.1;
    [stillImageSource addTarget:stillImageFilter];
    [stillImageSource processImage];
    UIImage *imageToProcess = [stillImageFilter imageFromCurrentlyProcessedOutput];

    RMImageTrimmingSides sides = RMImageTrimmingSidesAll;
    CGImageRef image = imageToProcess.CGImage;
    void * bitmapData = NULL;
    CGContextRef context = CKBitmapContextAndDataCreateWithImage(image, &bitmapData);

    Pixel *data = bitmapData;

    size_t width = CGBitmapContextGetWidth(context);
    size_t height = CGBitmapContextGetHeight(context);

    size_t top = 0;
    size_t bottom = height;
    size_t left = 0;
    size_t right = width;

    // Scan the left
    if (sides & RMImageTrimmingSidesLeft) {
        for (size_t x = 0; x < width; x++) {
            for (size_t y = 0; y < height; y++) {
                Pixel pixel = data[y * width + x];
                if (pixel.r != '\0' && pixel.g != '\0' && pixel.b != '\0') {
                    left = x;
                    goto SCAN_TOP;
                }
            }
        }
    }

    // Scan the top
SCAN_TOP:
    if (sides & RMImageTrimmingSidesTop) {
        for (size_t y = 0; y < height; y++) {
            for (size_t x = 0; x < width; x++) {
                Pixel pixel = data[y * width + x];
                if (pixel.r != '\0' && pixel.g != '\0' && pixel.b != '\0') {
                    top = y;
                    goto SCAN_RIGHT;
                }
            }
        }
    }

    // Scan the right
SCAN_RIGHT:
    if (sides & RMImageTrimmingSidesRight) {
        for (size_t x = width-1; x >= left; x--) {
            for (size_t y = 0; y < height; y++) {
                Pixel pixel = data[y * width + x];
                if (pixel.r != '\0' && pixel.g != '\0' && pixel.b != '\0') {
                    right = x;
                    goto SCAN_BOTTOM;
                }
            }
        }
    }

    // Scan the bottom
SCAN_BOTTOM:
    if (sides & RMImageTrimmingSidesBottom) {
        for (size_t y = height-1; y >= top; y--) {
            for (size_t x = 0; x < width; x++) {
                Pixel pixel = data[y * width + x];
                if (pixel.r != '\0' && pixel.g != '\0' && pixel.b != '\0') {
                    bottom = y;
                    goto FINISH;
                }
            }
        }
    }

FINISH:
    CGContextRelease(context);
    free(bitmapData);

    CGRect rect = CGRectMake(left, top, right - left, bottom - top);
    return [originalImage imageCroppedToRect:rect];
}

感谢上面代码中使用的库的开发人员所做的所有努力,当然所有的功劳都归功于他们!

答案 1 :(得分:1)

我已经调整了你的解决方案,因为GPUI的imageFromCurrentlyProcessedOutput方法已被删除,并被另一个根本不起作用的方法所取代。

还调整了图像的裁剪方式,并删除了一些刚被破坏的东西。似乎工作。

typedef struct Pixel { uint8_t r, g, b, a; } Pixel;

-(UIImage*)trimBlack:(UIImage*)originalImage {
    GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:originalImage];
    GPUImageLuminanceThresholdFilter *stillImageFilter = [[GPUImageLuminanceThresholdFilter alloc] init];
    stillImageFilter.threshold = 0.1;
    [stillImageSource addTarget:stillImageFilter];
    [stillImageSource processImage];
    [stillImageSource useNextFrameForImageCapture];
    
    //UIImage *imageToProcess = [stillImageFilter imageFromCurrentFramebufferWithOrientation:UIImageOrientationUp];
    //UIImage *imageToProcess = [UIImage imageWithCGImage:[stillImageFilter newCGImageFromCurrentlyProcessedOutput]];
    UIImage *imageToProcess = originalImage;
    
    //RMImageTrimmingSides sides = RMImageTrimmingSidesAll;
    CGImageRef image = imageToProcess.CGImage;
    void * bitmapData = NULL;
    CGContextRef context = CKBitmapContextAndDataCreateWithImage(image, &bitmapData);
    
    Pixel *data = bitmapData;
    
    size_t width = CGBitmapContextGetWidth(context);
    size_t height = CGBitmapContextGetHeight(context);
    
    size_t top = 0;
    size_t bottom = height;
    size_t left = 0;
    size_t right = width;
    
    // Scan the left
    //if (sides & RMImageTrimmingSidesLeft) {
        for (size_t x = 0; x < width; x++) {
            for (size_t y = 0; y < height; y++) {
                Pixel pixel = data[y * width + x];
                if (pixel.r != '\0' && pixel.g != '\0' && pixel.b != '\0') {
                    left = x;
                    goto SCAN_TOP;
                }
            }
        }
    //}
    
    // Scan the top
SCAN_TOP:
    //if (sides & RMImageTrimmingSidesTop) {
        for (size_t y = 0; y < height; y++) {
            for (size_t x = 0; x < width; x++) {
                Pixel pixel = data[y * width + x];
                if (pixel.r != '\0' && pixel.g != '\0' && pixel.b != '\0') {
                    top = y;
                    goto SCAN_RIGHT;
                }
            }
        }
    //}
    
    // Scan the right
SCAN_RIGHT:
    //if (sides & RMImageTrimmingSidesRight) {
        for (size_t x = width-1; x >= left; x--) {
            for (size_t y = 0; y < height; y++) {
                Pixel pixel = data[y * width + x];
                if (pixel.r != '\0' && pixel.g != '\0' && pixel.b != '\0') {
                    right = x;
                    goto SCAN_BOTTOM;
                }
            }
        }
    //}
    
    // Scan the bottom
SCAN_BOTTOM:
    //if (sides & RMImageTrimmingSidesBottom) {
        for (size_t y = height-1; y >= top; y--) {
            for (size_t x = 0; x < width; x++) {
                Pixel pixel = data[y * width + x];
                if (pixel.r != '\0' && pixel.g != '\0' && pixel.b != '\0') {
                    bottom = y;
                    goto FINISH;
                }
            }
        }
    //}
    
FINISH:
    CGContextRelease(context);
    free(bitmapData);
    
    CGRect rect = CGRectMake(left, top, right - left, bottom - top);
    CGImageRef imageRef = CGImageCreateWithImageInRect([originalImage CGImage], rect);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return croppedImage;
}