如何在iOS中为已有图片添加可调节强度的高斯噪声?
为图片添加可调节强度的高斯噪声(仿Photoshop滤镜)
现有方案的补充说明
之前找到的两种方案分别是生成纯噪声图、将噪声与背景混合,但缺少针对已有图片的可调节强度高斯噪声实现,且原噪声是均匀随机噪声,并非Photoshop滤镜使用的高斯分布噪声。以下是完整实现方案:
步骤1:生成高斯分布噪声图
使用Box-Muller变换生成符合正态分布的随机值(模拟高斯噪声),同时支持强度调节:
CGImageRef CGGenerateGaussianNoiseImage(CGSize size, CGFloat intensity) CF_RETURNS_RETAINED { // 强度范围映射:0~1 → 噪声幅度0~127(避免过曝) CGFloat noiseAmplitude = intensity * 127.0; NSUInteger pixelCount = (NSUInteger)fabs(size.width) * (NSUInteger)fabs(size.height); unsigned char *grayPixels = (unsigned char *)malloc(pixelCount); if (!grayPixels) return NULL; // Box-Muller变换生成高斯分布随机数 for (NSUInteger i = 0; i < pixelCount; i++) { CGFloat u1 = ((CGFloat)rand() / RAND_MAX); CGFloat u2 = ((CGFloat)rand() / RAND_MAX); CGFloat z0 = sqrt(-2.0 * log(u1)) * cos(2.0 * M_PI * u2); // 将高斯值映射到0~255灰度范围,中心值128(中性灰) CGFloat noiseValue = 128.0 + z0 * noiseAmplitude; grayPixels[i] = (unsigned char)CLAMP(noiseValue, 0.0, 255.0); } CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); CGContextRef context = CGBitmapContextCreate(grayPixels, (size_t)fabs(size.width), (size_t)fabs(size.height), 8, (size_t)fabs(size.width), colorSpace, kCGImageAlphaNone); CGImageRef noiseImage = CGBitmapContextCreateImage(context); // 释放资源 CFRelease(context); CGColorSpaceRelease(colorSpace); free(grayPixels); return noiseImage; } // 辅助宏:限制数值范围 #define CLAMP(value, min, max) ((value) < (min) ? (min) : ((value) > (max) ? (max) : (value)))
步骤2:将高斯噪声与已有图片混合
创建画布上下文,先绘制原图,再将噪声图按强度叠加(用kCGBlendModeOverlay模拟Photoshop“添加杂色”的视觉效果):
UIImage *addGaussianNoiseToImage(UIImage *originalImage, CGFloat intensity) { if (!originalImage) return nil; CGSize imageSize = originalImage.size; UIGraphicsBeginImageContextWithOptions(imageSize, NO, originalImage.scale); CGContextRef context = UIGraphicsGetCurrentContext(); // 绘制原图 [originalImage drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)]; // 生成对应尺寸的高斯噪声图 CGImageRef noiseImage = CGGenerateGaussianNoiseImage(imageSize, intensity); if (noiseImage) { // 设置混合模式与透明度,双重控制噪声强度 CGContextSetBlendMode(context, kCGBlendModeOverlay); CGContextSetAlpha(context, intensity); CGContextDrawImage(context, CGRectMake(0, 0, imageSize.width, imageSize.height), noiseImage); CFRelease(noiseImage); } UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultImage; }
使用示例
// 给已有图片添加强度为0.3的高斯噪声 UIImage *original = [UIImage imageNamed:@"test.jpg"]; UIImage *noisyImage = addGaussianNoiseToImage(original, 0.3);
内容的提问来源于stack exchange,提问作者erotsppa
相关产品推荐
相关产品推荐

