馬賽克算法及iOS代碼實現

  以前作了一下相關塗鴉的東西,發現圖片處理挺好玩的,就先講講馬賽克的實現吧。ide

  放大馬賽克圖片能夠看到,能夠看到一個個單色的小正方形。因此馬賽克其實也就是把某一點的色值填充了它必定範圍內的一個正方形,這樣看起來就會模糊,但總體仍是有必定原來的樣子。如圖,一張圖片能夠認爲是9*9個色值組成的位圖,進行馬賽克轉換就變成: spa

         轉換爲           3d

 

可知,就是把某一位的色值向右向下填充一個2*2的正方形。code

iOS代碼以下:blog

#define kBitsPerComponent (8)
#define kBitsPerPixel (32)
#define kPixelChannelCount (4)

/*
 *轉換成馬賽克,level表明一個點轉爲多少level*level的正方形
 */
+ (UIImage *)transToMosaicImage:(UIImage*)orginImage blockLevel:(NSUInteger)level
{
    //獲取BitmapData
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGImageRef imgRef = orginImage.CGImage;
    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);
    CGContextRef context = CGBitmapContextCreate (nil,
                                                  width,
                                                  height,
                                                  kBitsPerComponent,        //每一個顏色值8bit
                                                  width*kPixelChannelCount, //每一行的像素點佔用的字節數,每一個像素點的ARGB四個通道各佔8個bit
                                                  colorSpace,
                                                  kCGImageAlphaPremultipliedLast);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imgRef);
    unsigned char *bitmapData = CGBitmapContextGetData (context);
    
    //這裏把BitmapData進行馬賽克轉換,就是用一個點的顏色填充一個level*level的正方形
    unsigned char pixel[kPixelChannelCount] = {0};
    NSUInteger index,preIndex;
    for (NSUInteger i = 0; i < height - 1 ; i++) {
        for (NSUInteger j = 0; j < width - 1; j++) {
            index = i * width + j;        
            if (i % level == 0) {
                if (j % level == 0) {
                    memcpy(pixel, bitmapData + kPixelChannelCount*index, kPixelChannelCount);
                }else{
                    memcpy(bitmapData + kPixelChannelCount*index, pixel, kPixelChannelCount);
                }
            } else {
                preIndex = (i-1)*width +j;   
                memcpy(bitmapData + kPixelChannelCount*index, bitmapData + kPixelChannelCount*preIndex, kPixelChannelCount); } } } 
    NSInteger dataLength = width*height* kPixelChannelCount;
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmapData, dataLength, NULL);
    //建立要輸出的圖像
    CGImageRef mosaicImageRef = CGImageCreate(width, height,
                                        kBitsPerComponent,
                                        kBitsPerPixel,
                                        width*kPixelChannelCount ,
                                        colorSpace,
                                        kCGImageAlphaPremultipliedLast,
                                        provider,
                                        NULL, NO,
                                        kCGRenderingIntentDefault);
     CGContextRef outputContext = CGBitmapContextCreate(nil,
                                                 width,
                                                 height,
                                                 kBitsPerComponent,
                                                 width*kPixelChannelCount,
                                                 colorSpace,
                                                kCGImageAlphaPremultipliedLast);
    CGContextDrawImage(outputContext, CGRectMake(0.0f, 0.0f, width, height), mosaicImageRef);
    CGImageRef resultImageRef = CGBitmapContextCreateImage(outputContext);
    UIImage *resultImage = nil;
    if([UIImage respondsToSelector:@selector(imageWithCGImage:scale:orientation:)]) {
        float scale = [[UIScreen mainScreen] scale];
        resultImage = [UIImage imageWithCGImage:resultImageRef scale:scale orientation:UIImageOrientationUp];
    } else {
        resultImage = [UIImage imageWithCGImage:resultImageRef];
    }
    //釋放
    if(resultImageRef){
        CFRelease(resultImageRef);
    }
    if(mosaicImageRef){
        CFRelease(mosaicImageRef);
    }
    if(colorSpace){
        CGColorSpaceRelease(colorSpace);
    }
    if(provider){
        CGDataProviderRelease(provider);
    }
    if(context){
        CGContextRelease(context);
    }
    if(outputContext){
        CGContextRelease(outputContext);
    }
    return [[resultImage retain] autorelease];

}

 

其實主要代碼就是裏面那層作的馬賽克轉換,先後都是爲了獲取bitmapdata和把bitmapdata再還原爲圖像。圖片

 

你們能夠看看效果吧,這裏level選爲10.(圖片來自百度百科,不涉及侵權哈)ip

 

 

發現圖片處理確實挺好玩的。圖片處理

相關文章
相關標籤/搜索