中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

iOS實(shí)現(xiàn)毛玻璃效果,圖片模糊效果的三種方法

2018-07-20    來源:open-open

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用

App設(shè)計(jì)時(shí)往往會(huì)用到一些模糊效果或者毛玻璃效果,iOS目前已提供一些模糊API可以讓我們方便是使用。


第一種使用Core Image進(jìn)行模糊

- (UIImage *)blurryImage:(UIImage *)image   
           withBlurLevel:(CGFloat)blur {  
    CIImage *inputImage = [CIImage imageWithCGImage:image.CGImage];  
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"  
                         keysAndValues:kCIInputImageKey, inputImage,  
                                       @"inputRadius", @(blur),   
                                       nil];  
       
    CIImage *outputImage = filter.outputImage;  
       
    CGImageRef outImage = [self.context createCGImage:outputImage   
                                   fromRect:[outputImage extent]];  
    return [UIImage imageWithCGImage:outImage];  
}

第二種使用vImage API進(jìn)行模糊

- (UIImage *)blurryImage:(UIImage *)image withBlurLevel:(CGFloat)blur {  
    if (blur < 0.f || blur > 1.f) {  
        blur = 0.5f;  
    }  
    int boxSize = (int)(blur * 100);  
    boxSize = boxSize - (boxSize % 2) + 1;  
       
    CGImageRef img = image.CGImage;  
       
    vImage_Buffer inBuffer, outBuffer;  
    vImage_Error error;  
       
    void *pixelBuffer;  
       
    CGDataProviderRef inProvider = CGImageGetDataProvider(img);  
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);  
       
    inBuffer.width = CGImageGetWidth(img);  
    inBuffer.height = CGImageGetHeight(img);  
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);  
       
    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);  
       
    pixelBuffer = malloc(CGImageGetBytesPerRow(img) *   
                         CGImageGetHeight(img));  
       
    if(pixelBuffer == NULL)  
        NSLog(@"No pixelbuffer");  
       
    outBuffer.data = pixelBuffer;  
    outBuffer.width = CGImageGetWidth(img);  
    outBuffer.height = CGImageGetHeight(img);  
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);  
       
    error = vImageBoxConvolve_ARGB8888(&inBuffer,   
                                       &outBuffer,   
                                       NULL,   
                                       0,   
                                       0,   
                                       boxSize,   
                                       boxSize,   
                                       NULL,   
                                       kvImageEdgeExtend);  
       
       
    if (error) {  
        NSLog(@"error from convolution %ld", error);  
    }  
       
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();  
    CGContextRef ctx = CGBitmapContextCreate(  
                                    outBuffer.data,  
                                    outBuffer.width,  
                                    outBuffer.height,  
                                    8,  
                                    outBuffer.rowBytes,  
                                    colorSpace,  
                                    kCGImageAlphaNoneSkipLast);  
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);  
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];  
       
    //clean up  
    CGContextRelease(ctx);  
    CGColorSpaceRelease(colorSpace);  
       
    free(pixelBuffer);  
    CFRelease(inBitmapData);  
       
    CGColorSpaceRelease(colorSpace);  
    CGImageRelease(imageRef);  
       
    return returnImage;  
}  

第三種方法是網(wǎng)上找到的(毛玻璃效果)

// 內(nèi)部方法,核心代碼,封裝了毛玻璃效果 參數(shù):半徑,顏色,色彩飽和度
- (UIImage *)imageBluredWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage {
    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) {
            CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
            NSUInteger 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, (short)radius, (short)radius, 0, kvImageEdgeExtend);
            vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, (short)radius, (short)radius, 0, kvImageEdgeExtend);
            vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (short)radius, (short)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();
    }
    
    // 開啟上下文 用于輸出圖像
    UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
    CGContextRef outputContext = UIGraphicsGetCurrentContext();
    CGContextScaleCTM(outputContext, 1.0, -1.0);
    CGContextTranslateCTM(outputContext, 0, -self.size.height);
    
    // 開始畫底圖
    CGContextDrawImage(outputContext, imageRect, self.CGImage);
    
    // 開始畫模糊效果
    if (hasBlur) {
        CGContextSaveGState(outputContext);
        if (maskImage) {
            CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);
        }
        CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);
        CGContextRestoreGState(outputContext);
    }
    
    // 添加顏色渲染
    if (tintColor) {
        CGContextSaveGState(outputContext);
        CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
        CGContextFillRect(outputContext, imageRect);
        CGContextRestoreGState(outputContext);
    }
    
    // 輸出成品,并關(guān)閉上下文
    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return outputImage;
}


標(biāo)簽: swap 代碼

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:啟動(dòng)APK的默認(rèn)Activity

下一篇:ApachePOI 動(dòng)態(tài)列表生成excel