修剪UIImage白色边框
我无法find一种方法来裁剪包含白色边框的图像。
目前这是一个UIImage,我尝试了一些解决scheme,如UIImage + Trim和CKImageAddons,但这些库不工作。 我认为问题的一部分是,由于图像压缩(我认为), 边框不是完美的白色 。
有没有人find这个解决scheme?
谢谢,
那么,我会使用UIImage + Trim,并改变它的工作方式,以计数可见的白色像素(所以如果RGB> 255 – small_number_that_still_makes_it_white_but_suffices_to_cut_like_5_to_10)的计数不透明。
快看后,计数循环在这里:
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。
此外,它似乎创build用于计数的内部图像:
CGContextRef contextRef = CGBitmapContextCreate(bitmapData, (NSUInteger)width, (NSUInteger)height, 8, (NSUInteger)bytesPerRow, NULL, kCGImageAlphaOnly);
使用灰度图像应该可以轻松地将其从透明度testing更改为颜色testing。
编辑:好的,解决scheme:
- (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; }