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

我找到了一个库,但是它似乎不起作用。当我传入一个UIColor (带有RGB颜色)时,它只返回相同的图像。
我可以找到很多示例和类别类,它们可以用任何透明像素作为边框来修剪UIImage,但是在这种情况下,我需要修剪黑色。我已经在我的图像中取样了颜色,它们的颜色值确实是255,但它似乎不符合上述图书馆正在寻找的内容。
是否有人有他们使用过的图书馆或任何洞察力?我已经搜索和搜索,CKImageAdditions是我唯一能找到的东西,广告上有一种颜色(但不幸的是,在我的情况下不起作用)。
发布于 2014-01-06 20:08:31
最后,我从一个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];
}感谢上述代码中使用的库开发人员的辛勤工作,当然,所有的功劳都归于他们!
发布于 2016-02-04 00:33:46
我调整了您的解决方案,因为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;
}
https://stackoverflow.com/questions/20056870
复制相似问题