当前位置: 首页 > news >正文

iOS 如何对整张图分别局部磨砂,并完全贴合

官方磨砂方式

- (UIVisualEffectView *)effectView{if(!_effectView){UIBlurEffect *blur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];_effectView = [[UIVisualEffectView alloc] initWithEffect:blur];}return _effectView;
}

使用这种方式对一张图的上半部分和下半部分分别磨砂,并进行拼接,然后发现效果是这样的,请添加图片描述

即两个部分有明显的界限,无法完全贴合

自己生成新的磨砂图片

给UIImage添加一个分类,添加如下方法


- (UIImage *)applyLightEffect
{UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
}- (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage
{// Check pre-conditions.if (self.size.width < 1 || self.size.height < 1) {TPLOG (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);return nil;}if (!self.CGImage) {TPLOG (@"*** error: image must be backed by a CGImage: %@", self);return nil;}if (maskImage && !maskImage.CGImage) {TPLOG (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);return nil;}CGRect imageRect = { CGPointZero, self.size };UIImage *effectImage = self;BOOL hasBlur = blurRadius > __FLT_EPSILON__;BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;if (hasBlur || hasSaturationChange) {UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);CGContextRef effectInContext = UIGraphicsGetCurrentContext();CGContextScaleCTM(effectInContext, 1.0, -1.0);CGContextTranslateCTM(effectInContext, 0, -self.size.height);CGContextDrawImage(effectInContext, imageRect, self.CGImage);vImage_Buffer effectInBuffer;effectInBuffer.data     = CGBitmapContextGetData(effectInContext);effectInBuffer.width    = CGBitmapContextGetWidth(effectInContext);effectInBuffer.height   = CGBitmapContextGetHeight(effectInContext);effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);CGContextRef effectOutContext = UIGraphicsGetCurrentContext();vImage_Buffer effectOutBuffer;effectOutBuffer.data     = CGBitmapContextGetData(effectOutContext);effectOutBuffer.width    = CGBitmapContextGetWidth(effectOutContext);effectOutBuffer.height   = CGBitmapContextGetHeight(effectOutContext);effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);if (hasBlur) {// A description of how to compute the box kernel width from the Gaussian// radius (aka standard deviation) appears in the SVG spec:// http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement//// For larger values of 's' (s >= 2.0), an approximation can be used: Three// successive box-blurs build a piece-wise quadratic convolution kernel, which// approximates the Gaussian kernel to within roughly 3%.//// let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)//// ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.//CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];int radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);if (radius % 2 != 1) {radius += 1; // force radius to be odd so that the three box-blur methodology works.}vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0,radius, radius, 0, kvImageEdgeExtend);vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend);}BOOL effectImageBuffersAreSwapped = NO;if (hasSaturationChange) {CGFloat s = saturationDeltaFactor;CGFloat floatingPointSaturationMatrix[] = {0.0722 + 0.9278 * s,  0.0722 - 0.0722 * s,  0.0722 - 0.0722 * s,  0,0.7152 - 0.7152 * s,  0.7152 + 0.2848 * s,  0.7152 - 0.7152 * s,  0,0.2126 - 0.2126 * s,  0.2126 - 0.2126 * s,  0.2126 + 0.7873 * s,  0,0,                    0,                    0,  1,};const int32_t divisor = 256;NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);int16_t saturationMatrix[matrixSize];for (NSUInteger i = 0; i < matrixSize; ++i) {saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);}if (hasBlur) {vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);effectImageBuffersAreSwapped = YES;}else {vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);}}if (!effectImageBuffersAreSwapped)effectImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();if (effectImageBuffersAreSwapped)effectImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();}// Set up output context.UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);CGContextRef outputContext = UIGraphicsGetCurrentContext();CGContextScaleCTM(outputContext, 1.0, -1.0);CGContextTranslateCTM(outputContext, 0, -self.size.height);// Draw base image.CGContextDrawImage(outputContext, imageRect, self.CGImage);// Draw effect image.if (hasBlur) {CGContextSaveGState(outputContext);if (maskImage) {CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);}CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);CGContextRestoreGState(outputContext);}// Add in color tint.if (tintColor) {CGContextSaveGState(outputContext);CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);CGContextFillRect(outputContext, imageRect);CGContextRestoreGState(outputContext);}// Output image is ready.UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return outputImage;
}

外面使用

    UIImage *blurImage = [image applyLightEffect];self.bannerView.image = blurImage;

效果图
请添加图片描述
上下完全贴合
综上所述,如果某清情况下我们要分别对图片进行磨砂,并式两个图片完全贴合,则可以使用 这种磨砂方式

http://www.lryc.cn/news/138209.html

相关文章:

  • Packet_Tracer的使用
  • WPF如果未定义绑定的属性,程序如何处理
  • 韩国留学生生活之-租房篇,柯桥韩语培训留学韩语需要学到什么程度
  • 论文笔记:基于概念漂移的在线类非平衡学习系统研究
  • ubuntu22.04下rv1109 rootfs编译问题处理
  • Spring Boot Dubbo Zookeeper
  • 线程池的概念及实现原理
  • iOS App逆向之:iOS应用砸壳技术
  • 【高性能计算】opencl安装及相关概念
  • 盛最多水的容器——力扣11
  • 2023年高教社杯数学建模思路 - 复盘:校园消费行为分析
  • Flink_state 的优化与 remote_state 的探索
  • Kdab QML (part9)自由缩放时钟
  • Java网络编程(二)经典案例[粘包拆包]
  • 无分布式锁的ID生成
  • X2000 Linux UVC
  • HCIP-OpenStack组件之neutron
  • 数学建模-常见算法(3)
  • 缓存的设计方式
  • CH02_重构的原则(什么是重构、为什么重构、何时重构)
  • 26. 删除有序数组中的重复项(简单系列)
  • 【linux】基本指令(二)【man、echo、cat、cp】
  • 【视频】Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析|数据分享...
  • 2023年7月京东空气净化器行业品牌销售排行榜(京东运营数据分析)
  • 原生小案例:如何使用HTML5 Canvas构建画板应用程序
  • Electron 报gpu_process_host.cc(951)] GPU process launch faile错误
  • 每天一分享#读up有感#
  • threejs贴图系列(一)canvas贴图
  • taro react/vue h5 中的上传input onchange 值得区别
  • (AcWing) 任务安排(I,II,III)