修剪 UIImage 白色边框 [英] Trimming UIImage white borders

查看:38
本文介绍了修剪 UIImage 白色边框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到裁剪包含白色边框的图像的方法.

I can't find a way to crop an image with white borders included.

目前它是一个 UIImage,我尝试了一些解决方案,例如 UIImage+TrimCKImageAddons 但这些库不起作用.我认为部分问题在于边界不是完全白色,因为图像压缩(我认为).

Currently it's an UIImage, and I tried some solutions like UIImage+Trim and CKImageAddons but those libraries didn't work. I think part of the problem is that the borders is not perfectly white because of image compression (I think).

有没有人为此找到解决方案?

Has anyone find a solution for this?

谢谢,

推荐答案

嗯,我会使用 UIImage+Trim 并改变它的工作方式来计算明显的白色像素(所以如果 RGB > 255 - small_number_that_still_makes_it_white_but_suffices_to_cut_like_5_to_10),不再计算非-透明.

Well, I would use UIImage+Trim and changed the way it works to count visibly white pixels (so if RGB > 255 - small_number_that_still_makes_it_white_but_suffices_to_cut_like_5_to_10) insted of counting non-transparent.

快速浏览后,计数循环在这里:

After quick look, the counting loop is here:

for (NSInteger row = 0; row < height; row++) {

    for (NSInteger col = 0; col < width; col++) {

        if (fullyOpaque) {

            // Found non-transparent pixel
            if (bitmapData[row*bytesPerRow + col] == UINT8_MAX) {

                rowSum[row]++;
                colSum[col]++;

            }

        } else {

            // Found non-transparent pixel
            if (bitmapData[row*bytesPerRow + col]) {

                rowSum[row]++;
                colSum[col]++;

            }

        }

    }

}

和切割在下面完成,并删除等于0的rowSum和colSum.

and cutting is done below, and removes rowSum and colSum that are equal to 0.

此外,它似乎创建了用于计数的内部图像:

Also, it seems it creates inner image that is used for counting:

CGContextRef contextRef = CGBitmapContextCreate(bitmapData, (NSUInteger)width, (NSUInteger)height, 8, (NSUInteger)bytesPerRow, NULL, kCGImageAlphaOnly);

改用灰度图像应该是将其从透明度测试更改为颜色测试的简单方法.

Using a grayscale image instead should work as easy way to change it from transparency testing to color testing.

好的,解决方案:

- (UIEdgeInsets)transparencyInsetsByCuttingWhitespace:(UInt8)tolerance
{
    // Draw our image on that context
    NSInteger width  = (NSInteger)CGImageGetWidth([self CGImage]);
    NSInteger height = (NSInteger)CGImageGetHeight([self CGImage]);
    NSInteger bytesPerRow = width * (NSInteger)sizeof(uint8_t);

    // Allocate array to hold alpha channel
    uint8_t * bitmapData = calloc((size_t)(width * height), sizeof(uint8_t));

    // Create grayscale image
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
    CGContextRef contextRef = CGBitmapContextCreate(bitmapData, (NSUInteger)width, (NSUInteger)height, 8, (NSUInteger)bytesPerRow, colorSpace, kCGImageAlphaNone);

    CGImageRef cgImage = self.CGImage;
    CGRect rect = CGRectMake(0, 0, width, height);
    CGContextDrawImage(contextRef, rect, cgImage);

    // Sum all non-transparent pixels in every row and every column
    uint16_t * rowSum = calloc((size_t)height, sizeof(uint16_t));
    uint16_t * colSum = calloc((size_t)width,  sizeof(uint16_t));

    // Enumerate through all pixels
    for (NSInteger row = 0; row < height; row++) {

        for (NSInteger col = 0; col < width; col++) {

            // Found darker pixel
            if (bitmapData[row*bytesPerRow + col] <= UINT8_MAX - tolerance) {

                rowSum[row]++;
                colSum[col]++;

            }
        }
    }

    // Initialize crop insets and enumerate cols/rows arrays until we find non-empty columns or row
    UIEdgeInsets crop = UIEdgeInsetsZero;

    // Top
    for (NSInteger i = 0; i < height; i++) {

        if (rowSum[i] > 0) {

            crop.top = i;
            break;

        }

    }

    // Bottom
    for (NSInteger i = height - 1; i >= 0; i--) {

        if (rowSum[i] > 0) {
            crop.bottom = MAX(0, height - i - 1);
            break;
        }

    }

    // Left
    for (NSInteger i = 0; i < width; i++) {

        if (colSum[i] > 0) {
            crop.left = i;
            break;
        }

    }

    // Right
    for (NSInteger i = width - 1; i >= 0; i--) {

        if (colSum[i] > 0) {

            crop.right = MAX(0, width - i - 1);
            break;

        }
    }

    free(bitmapData);
    free(colSum);
    free(rowSum);

    CGContextRelease(contextRef);

    return crop;
}

- (UIImage *)imageByTrimmingWhitePixelsWithOpacity:(UInt8)tolerance
{
    if (self.size.height < 2 || self.size.width < 2) {

        return self;

    }

    CGRect rect = CGRectMake(0, 0, self.size.width * self.scale, self.size.height * self.scale);
    UIEdgeInsets crop = [self transparencyInsetsByCuttingWhitespace:tolerance];

    UIImage *img = self;

    if (crop.top == 0 && crop.bottom == 0 && crop.left == 0 && crop.right == 0) {

        // No cropping needed

    } else {

        // Calculate new crop bounds
        rect.origin.x += crop.left;
        rect.origin.y += crop.top;
        rect.size.width -= crop.left + crop.right;
        rect.size.height -= crop.top + crop.bottom;

        // Crop it
        CGImageRef newImage = CGImageCreateWithImageInRect([self CGImage], rect);

        // Convert back to UIImage
        img = [UIImage imageWithCGImage:newImage scale:self.scale orientation:self.imageOrientation];

        CGImageRelease(newImage);
    }

    return img;
}

这篇关于修剪 UIImage 白色边框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆