修剪UIImage边框

这是一个我想修剪的图像的例子。 我想摆脱图像周围的边界(在这种情况下,顶部和底部的黑色条)。

UIImage修剪

我在Github上find一个库: CKImageAdditions ,但是它似乎没有工作。 当我通过一个UIColor(与RGB颜色)它只是返回相同的图像。

我可以find很多的示例和类的类,将修剪UIImage与任何透明的像素作为边界,但在这种情况下,我需要修剪黑色。 我已经在我的图像中抽取了颜色,他们的颜色值确实是255,但它似乎不符合上面的库正在寻找。

有没有人有他们使用的图书馆或任何见解? 我search和searchCKImageAdditions一直是我可以find广告修剪颜色(但不幸的是在我的情况下不工作)的唯一的东西。

我从CKImageAdditions中的一个函数中定制了一个方法,它具有这个function,但我无法使其工作。 它只是不会修剪颜色,所以我反而检查像素的RGB值是\0 (黑色)。 CKImageAdditions是, CKImageAdditions找不到黑色像素。

由于我想修剪的图像有时没有超级黑条(有时它们会有一个更浅的深色的杂散像素或其他东西)我添加了GPUImagefunction的方法,基本上只是创build一个黑白版本的图像上有一个强大的filter,所以任何深色变黑,任何浅色变成白色,使黑条边界更加突出,并确保更好的结果,当我在他们的方法。 当然,我最后根据黑白图像的结果裁剪原始图像。

这是我的代码:

 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]; } 

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

我调整了你的解决scheme,现在GPUImage的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; }