我尝试了高斯模糊并检查了stackoverflow上的所有问题,但没有一个解决了我的崩溃问题。请帮助除了高斯模糊算法之外还有其他任何模糊图像的方法。我的图像大小是768x1024,循环迭代2 * 1024 * 768次,这是不可行的。
CGContextRef NYXImageCreateARGBBitmapContext(const size_t width, const size_t height, const size_t bytesPerRow)
{
/// Use the generic RGB color space
/// We avoid the NULL check because CGColorSpaceRelease() NULL check the value anyway, and worst case scenario = fail to create context
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
/// Create the bitmap context, we want pre-multiplied ARGB, 8-bits per component
CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8/*Bits per component*/, bytesPerRow, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);
return bmContext;
}
-(UIImage*)blurredImageUsingGaussFactor:(NSUInteger)gaussFactor andPixelRadius:(NSUInteger)pixelRadius
{
CGImageRef cgImage = self.CGImage;
const size_t originalWidth = CGImageGetWidth(cgImage);
const size_t originalHeight = CGImageGetHeight(cgImage);
const size_t bytesPerRow = originalWidth * 4;
CGContextRef context = NYXImageCreateARGBBitmapContext(originalWidth, originalHeight, bytesPerRow);
if (!context)
return nil;
unsigned char *srcData, *destData, *finalData;
size_t width = CGBitmapContextGetWidth(context);
size_t height = CGBitmapContextGetHeight(context);
size_t bpr = CGBitmapContextGetBytesPerRow(context);
size_t bpp = CGBitmapContextGetBitsPerPixel(context) / 8;
CGRect rect = {{0.0f, 0.0f}, {width, height}};
CGContextDrawImage(context, rect, cgImage);
// Now we can get a pointer to the image data associated with the bitmap
// context.
srcData = (unsigned char*)CGBitmapContextGetData(context);
if (srcData != NULL)
{
size_t dataSize = bpr * height;
finalData = malloc(dataSize);
destData = malloc(dataSize);
memcpy(finalData, srcData, dataSize);
memcpy(destData, srcData, dataSize);
int sums[gaussFactor];
size_t i, /*x, y,*/ k;
int gauss_sum = 0;
size_t radius = pixelRadius * 2 + 1;
int *gauss_fact = malloc(radius * sizeof(int));
for (i = 0; i < pixelRadius; i++)
{
gauss_fact[i] = 1 + (gaussFactor * i);
gauss_fact[radius - (i + 1)] = 1 + (gaussFactor * i);
gauss_sum += (gauss_fact[i] + gauss_fact[radius - (i + 1)]);
}
gauss_fact[(radius - 1) / 2] = 1 + (gaussFactor*pixelRadius);
gauss_sum += gauss_fact[(radius - 1) / 2];
unsigned char *p1, *p2, *p3;
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
p1 = srcData + bpp * (y * width + x);
p2 = destData + bpp * (y * width + x);
for (i = 0; i < gaussFactor; i++)
sums[i] = 0;
for (k = 0; k < radius ; k++)
{
if ((y - ((radius - 1) >> 1) + k) < height)
p1 = srcData + bpp * ((y - ((radius - 1) >> 1) + k) * width + x);
else
p1 = srcData + bpp * (y * width + x);
for (i = 0; i < bpp; i++)
sums[i] += p1[i] * gauss_fact[k];
}
for (i = 0; i < bpp; i++)
p2[i] = sums[i] / gauss_sum;
}
}
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
p2 = destData + bpp * (y * width + x);
p3 = finalData + bpp * (y * width + x);
for (i = 0; i < gaussFactor; i++)
sums[i] = 0;
for(k = 0; k < radius ; k++)
{
if ((x - ((radius - 1) >> 1) + k) < width)
p1 = srcData + bpp * ( y * width + (x - ((radius - 1) >> 1) + k));
else
p1 = srcData + bpp * (y * width + x);
for (i = 0; i < bpp; i++)
sums[i] += p2[i] * gauss_fact[k];
}
for (i = 0; i < bpp; i++)
{
p3[i] = sums[i] / gauss_sum;
}
}
}
}
size_t bitmapByteCount = bpr * height;
///////Here was the problem.. you had given srcData instead of destData.. Rest all
//were perfect...
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL, destData, bitmapByteCount, NULL);
CGImageRef blurredImageRef = CGImageCreate(width, height, CGBitmapContextGetBitsPerComponent(context), CGBitmapContextGetBitsPerPixel(context), CGBitmapContextGetBytesPerRow(context), CGBitmapContextGetColorSpace(context), CGBitmapContextGetBitmapInfo(context), dataProvider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(dataProvider);
CGContextRelease(context);
if (destData)
free(destData);
if (finalData)
free(finalData);
UIImage* retUIImage = [UIImage imageWithCGImage:blurredImageRef];
CGImageRelease(blurredImageRef);
return retUIImage;
}
答案 0 :(得分:15)
我为UIImage做了一个小的StackBlur扩展。 StackBlur接近GaussianBlur但速度更快。
请查看:https://github.com/tomsoft1/StackBluriOS
微小的音符 ...只是在ReadMe上有一个拼写错误,“规范化”为“normalize”
答案 1 :(得分:2)
不确定如何模糊图像。
这可能有助于您blur an UIImageView or any view
。
UIView *myView = self.theImageView;
CALayer *layer = [myView layer];
[layer setRasterizationScale:0.25];
[layer setShouldRasterize:YES];
您可以通过将光栅化比例设置回1来撤消它。
[layer setRasterizationScale:1.0];
<强>更新强>
以下Apple示例代码包含模糊/清晰效果。 (使用Open GL) 看看是否有帮助,http://developer.apple.com/library/ios/#samplecode/GLImageProcessing/Introduction/Intro.html
答案 2 :(得分:1)
你可能想要的是Box Blur算法。它比高斯模糊快约10倍,并产生很好的效果。我有在Android上运行的代码,我还没有将它移植到iOS。这是source。
只需大约10分钟即可移植到iOS。这些函数将按原样运行,您只需访问图像字节(就像您在上面的源代码中所做的那样)并将它们提供给函数。