首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Trim UIImage边界

Trim UIImage边界
EN

Stack Overflow用户
提问于 2013-11-18 20:10:13
回答 2查看 1.7K关注 0票数 5

这是一个我想要修剪的图像的例子。我想去掉图像周围的边框(在本例中是顶部和底部的黑条)。

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

我可以找到很多示例和类别类,它们可以用任何透明像素作为边框来修剪UIImage,但是在这种情况下,我需要修剪黑色。我已经在我的图像中取样了颜色,它们的颜色值确实是255,但它似乎不符合上述图书馆正在寻找的内容。

是否有人有他们使用过的图书馆或任何洞察力?我已经搜索和搜索,CKImageAdditions是我唯一能找到的东西,广告上有一种颜色(但不幸的是,在我的情况下不起作用)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-06 20:08:31

最后,我从一个CKImageAdditions中的函数中定制了一个方法,据说它具有这个功能,但我无法让它工作。它只是不会修剪颜色,所以我检查像素的RGB值为\0 (黑色)。不幸的是,CKImageAdditions无法找到黑色像素。

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

这是我的密码:

代码语言:javascript
复制
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];
}

感谢上述代码中使用的库开发人员的辛勤工作,当然,所有的功劳都归于他们!

票数 7
EN

Stack Overflow用户

发布于 2016-02-04 00:33:46

我调整了您的解决方案,因为GPUImage的imageFromCurrentlyProcessedOutput方法已经被移除,取而代之的是另一个根本无法工作的方法。

还调整了图像的裁剪和删除一些刚刚被破坏的东西。似乎很管用。

代码语言:javascript
复制
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;
}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20056870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档