修剪UIImage的边界 [英] Trim UIImage border
问题描述
下面是我想裁剪图像的一个例子。我想摆脱图像周围的边框(在这种情况下,顶部和底部有黑条)。
Here's an example of an image I would like to trim. I want to get rid of the borders around the image (in this case the top and bottom black bars).
我发现在Github上库: CKImageAdditions ,但它似乎并没有工作。当我传递一个的UIColor(带RGB色彩),它只是返回相同的图像。
I found a library on Github: CKImageAdditions, however it doesn't seem to work. When I pass in a UIColor (with RGB colours) it just returns the same image.
我可以找到大量的实例和类别类,将修剪一个UIImage与任何透明像素为界,但在这种情况下,我需要修剪黑色。我已采样的颜色在我的图片和它们的颜色值确实是255,但它似乎并没有以匹配上面的库所期待的。
I can find a lot of examples and category classes that would trim a UIImage with any transparent pixels as the border, but in this case I need to trim the black colour. I have sampled the colour in my images and they the colour value is indeed 255, but it doesn't seem to match what the above library is looking for.
有没有人有他们所使用的库或任何见解?我已经搜查,搜查和CKImageAdditions一直是我能找到的唯一的事情是做广告用一种颜色来修剪(不过,遗憾的是没有在我的情况下工作)。
Does anyone have a library they have used or any insight? I've searched and searched and CKImageAdditions has been the only thing I can find that advertises to trim with a colour (although, unfortunately doesn't work in my case).
推荐答案
我结束了从定制的方法的<一个href=\"https://github.com/cmkilger/CKImageAdditions/blob/master/ImageAdditions/CoreGraphicsAdditions.c#L235\">function在假想有这个功能,但我无法得到它的工作CKImageAdditions 。它只是不会修剪的颜色,所以我代替检查像素的RGB值是 \\ 0
(黑色)。在 CKImageAdditions
只是找不到黑色像素,很遗憾。
I ended up customizing a method from a function in CKImageAdditions that had this functionality supposedly but I couldn't get it to work. It just wouldn't trim the colour, so I instead check the pixel's RGB values to be \0
(black). The CKImageAdditions
just couldn't find the black pixels, unfortunately.
因为我想有时修剪图像没有超黑条(有时他们不得不用打火机深色或一些流浪像素)我加的 GPUImage 功能的方法,它基本上只是在其创建的图像具有较强的过滤器的黑色和白色版本,所以任何黑暗的颜色变成黑色和任何浅色变成白色,使黑条边框更加突出,并确保更好的结果,当我的方法寻找他们。当然,我在基于从黑/白图像的结果结束裁剪原始图像
Since the images I wanted to trim sometimes didn't have super black bars (sometimes they'd have a stray pixel with a lighter dark colour or something) I added GPUImage functionality to the method, which basically just creates a black and white version of the image with a strong filter on it so any dark colours become black and any light colours become white, making the black bar borders much more prominent and ensuring better results when I look for them in the method. And of course I crop the original image at the end based on the results from the black/white image.
下面是我的code:
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];
}
由于从库中的code上面使用,当然所有归功于他们的开发人员所有的辛勤工作!
Thanks to all the hard work from the developers of the libraries used in the code above and of course all credit goes to them!
这篇关于修剪UIImage的边界的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!