iOS 圖片高斯模糊處理

? ? ? ? ? ? weakSelf.bgImageView.image= [imageblurImageAtFrame:CGRectMake(0,0, image.size.width, image.size.height)];




- (UIImage*)blurImageAtFrame:(CGRect)frame {




? ? return [self applyBlurWithRadius:20

?? ? ? ? ? ? ? ? ? ? ? ? ? tintColor:[UIColorcolorWithWhite:0alpha:0.0]

?? ? ? ? ? ? ? saturationDeltaFactor:1.4

?? ? ? ? ? ? ? ? ? ? ? ? ? maskImage:nil

?? ? ? ? ? ? ? ? ? ? ? ? ? ? atFrame:frame];

}

- (UIImage*)applyBlurWithRadius:(CGFloat)blurRadiustintColor:(UIColor*)tintColorsaturationDeltaFactor:(CGFloat)saturationDeltaFactormaskImage:(UIImage*)maskImage {


? ? // Check pre-conditions.

? ? if(self.size.width<1||self.size.height<1) {


? ? ? ? NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);

? ? ? ? returnnil;

? ? }


? ? if(!self.CGImage) {


? ? ? ? NSLog (@"*** error: image must be backed by a CGImage: %@", self);

? ? ? ? returnnil;

? ? }


? ? if(maskImage && !maskImage.CGImage) {


? ? ? ? NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);

? ? ? ? returnnil;

? ? }

? ? CGRect? imageRect? = {CGPointZero,self.size};

? ? UIImage*effectImage =self;


? ? BOOLhasBlur? ? ? ? ? ? = blurRadius >__FLT_EPSILON__;

? ? BOOLhasSaturationChange =fabs(saturationDeltaFactor -1.) >__FLT_EPSILON__;

? ? if(hasBlur || hasSaturationChange) {


? ? ? ? UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);

? ? ? ? CGContextRefeffectInContext =UIGraphicsGetCurrentContext();

? ? ? ? CGContextScaleCTM(effectInContext,1.0, -1.0);

? ? ? ? CGContextTranslateCTM(effectInContext,0, -self.size.height);

? ? ? ? CGContextDrawImage(effectInContext, imageRect,self.CGImage);

? ? ? ? vImage_BuffereffectInBuffer;

? ? ? ? effectInBuffer.data? ? =CGBitmapContextGetData(effectInContext);

? ? ? ? effectInBuffer.width? ? =CGBitmapContextGetWidth(effectInContext);

? ? ? ? effectInBuffer.height? =CGBitmapContextGetHeight(effectInContext);

? ? ? ? effectInBuffer.rowBytes=CGBitmapContextGetBytesPerRow(effectInContext);


? ? ? ? UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);

? ? ? ? CGContextRefeffectOutContext =UIGraphicsGetCurrentContext();

? ? ? ? vImage_BuffereffectOutBuffer;

? ? ? ? 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.

? ? ? ? ? ? //?

? ? ? ? ? ? CGFloatinputRadius = blurRadius * [[UIScreenmainScreen]scale];

? ? ? ? ? ? NSUIntegerradius =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, (uint32_t)radius, (uint32_t)radius,0,kvImageEdgeExtend);

? ? ? ? ? ? vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer,NULL,0,0, (uint32_t)radius, (uint32_t)radius,0,kvImageEdgeExtend);

? ? ? ? ? ? vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer,NULL,0,0, (uint32_t)radius, (uint32_t)radius,0,kvImageEdgeExtend);

? ? ? ? }


? ? ? ? BOOLeffectImageBuffersAreSwapped =NO;

? ? ? ? if(hasSaturationChange) {


? ? ? ? ? ? CGFloats = saturationDeltaFactor;

? ? ? ? ? ? CGFloatfloatingPointSaturationMatrix[] = {

? ? ? ? ? ? ? ? 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,

? ? ? ? ? ? };

? ? ? ? ? ? constint32_tdivisor =256;

? ? ? ? ? ? NSUIntegermatrixSize =sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);

? ? ? ? ? ? int16_tsaturationMatrix[matrixSize];


? ? ? ? ? ? for(NSUIntegeri =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();

? ? returnoutputImage;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市牺勾,隨后出現(xiàn)的幾起案子帘腹,更是在濱河造成了極大的恐慌琳省,老刑警劉巖短荐,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件器净,死亡現(xiàn)場離奇詭異碗暗,居然都是意外死亡亩鬼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門烘挫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來诀艰,“玉大人,你說我怎么就攤上這事饮六∑渎ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵卤橄,是天一觀的道長绿满。 經(jīng)常有香客問我,道長窟扑,這世上最難降的妖魔是什么喇颁? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮嚎货,結(jié)果婚禮上橘霎,老公的妹妹穿的比我還像新娘。我一直安慰自己殖属,他們只是感情好姐叁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般七蜘。 火紅的嫁衣襯著肌膚如雪谭溉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天橡卤,我揣著相機(jī)與錄音扮念,去河邊找鬼。 笑死碧库,一個胖子當(dāng)著我的面吹牛柜与,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嵌灰,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼弄匕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了沽瞭?” 一聲冷哼從身側(cè)響起迁匠,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎驹溃,沒想到半個月后城丧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡豌鹤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年亡哄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片布疙。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡蚊惯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出灵临,到底是詐尸還是另有隱情截型,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布儒溉,位于F島的核電站宦焦,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏睁搭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一笼平、第九天 我趴在偏房一處隱蔽的房頂上張望园骆。 院中可真熱鬧,春花似錦寓调、人聲如沸锌唾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晌涕。三九已至滋捶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間余黎,已是汗流浹背重窟。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惧财,地道東北人巡扇。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像垮衷,于是被迫代替她去往敵國和親厅翔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容