2013-03-15 28 views
3

我正在使用CIPixellate過濾器進行一些測試,我已使用該工具,但生成的圖像大小各不相同。我認爲這是有道理的,因爲我正在改變輸入的比例,但並不是我所期待的 - 我認爲它會在圖像的矩形內進行縮放。CIPixellate圖像輸出尺寸各不相同

我誤解/使用過濾器錯誤或我只需要裁剪輸出圖像到我想要的大小。

另外,inputCenter參數不明白從我讀取標題/試驗和錯誤。任何人都可以解釋那個參數是關於什麼的?

NSMutableArray * tmpImages = [[NSMutableArray alloc] init]; 
for (int i = 0; i < 10; i++) { 
    double scale = i * 4.0; 
    UIImage* tmpImg = [self applyCIPixelateFilter:self.faceImage withScale:scale]; 
    printf("tmpImg width: %f height: %f\n", tmpImg.size.width, tmpImg.size.height); 
    [tmpImages addObject:tmpImg]; 
} 

tmpImg width: 480.000000 height: 640.000000 
tmpImg width: 484.000000 height: 644.000000 
tmpImg width: 488.000000 height: 648.000000 
tmpImg width: 492.000000 height: 652.000000 
tmpImg width: 496.000000 height: 656.000000 
tmpImg width: 500.000000 height: 660.000000 
tmpImg width: 504.000000 height: 664.000000 
tmpImg width: 508.000000 height: 668.000000 
tmpImg width: 512.000000 height: 672.000000 
tmpImg width: 516.000000 height: 676.000000 

- (UIImage *)applyCIPixelateFilter:(UIImage*)fromImage withScale:(double)scale 
{ 
    /* 
    Makes an image blocky by mapping the image to colored squares whose color is defined by the replaced pixels. 
    Parameters 

    inputImage: A CIImage object whose display name is Image. 

    inputCenter: A CIVector object whose attribute type is CIAttributeTypePosition and whose display name is Center. 
    Default value: [150 150] 

    inputScale: An NSNumber object whose attribute type is CIAttributeTypeDistance and whose display name is Scale. 
    Default value: 8.00 
    */ 
    CIContext *context = [CIContext contextWithOptions:nil]; 
    CIFilter *filter= [CIFilter filterWithName:@"CIPixellate"]; 
    CIImage *inputImage = [[CIImage alloc] initWithImage:fromImage]; 
    CIVector *vector = [CIVector vectorWithX:fromImage.size.width /2.0f Y:fromImage.size.height /2.0f]; 
    [filter setDefaults]; 
    [filter setValue:vector forKey:@"inputCenter"]; 
    [filter setValue:[NSNumber numberWithDouble:scale] forKey:@"inputScale"]; 
    [filter setValue:inputImage forKey:@"inputImage"]; 

    CGImageRef cgiimage = [context createCGImage:filter.outputImage fromRect:filter.outputImage.extent]; 
    UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:1.0f orientation:fromImage.imageOrientation]; 

    CGImageRelease(cgiimage); 

    return newImage; 
} 
+0

不知道這是否會幫助,但嘗試的NSNumber numberWithFloat爲輸入標定 – Roecrew 2013-05-02 21:25:33

回答

0

有時inputScale不會平均分配你的形象,這是當我發現我得到大小不同的輸出圖像。

例如,如果inputScale = 0或1,則輸出圖像大小非常準確。

我發現圖像周圍的額外空間居中的方式因inputCenter「不透明」而異。也就是說,我沒有花時間弄清楚究竟是如何(我通過點擊位置來設置它)。

我對不同尺寸的解決方案是將圖像重新渲染到輸入圖像的大小範圍內,我在Apple Watch的黑色背景下進行渲染。

CIFilter *pixelateFilter = [CIFilter filterWithName:@"CIPixellate"]; 
[pixelateFilter setDefaults]; 
[pixelateFilter setValue:[CIImage imageWithCGImage:editImage.CGImage] forKey:kCIInputImageKey]; 
[pixelateFilter setValue:@(amount) forKey:@"inputScale"]; 
[pixelateFilter setValue:vector forKey:@"inputCenter"]; 
CIImage* result = [pixelateFilter valueForKey:kCIOutputImageKey];  
CIContext *context = [CIContext contextWithOptions:nil]; 
CGRect extent = [pixelateResult extent]; 
CGImageRef cgImage = [context createCGImage:result fromRect:extent]; 

UIGraphicsBeginImageContextWithOptions(editImage.size, YES, [editImage scale]); 
CGContextRef ref = UIGraphicsGetCurrentContext(); 
CGContextTranslateCTM(ref, 0, editImage.size.height); 
CGContextScaleCTM(ref, 1.0, -1.0); 

CGContextSetFillColorWithColor(ref, backgroundFillColor.CGColor); 
CGRect drawRect = (CGRect){{0,0},editImage.size}; 
CGContextFillRect(ref, drawRect); 
CGContextDrawImage(ref, drawRect, cgImage); 
UIImage* filledImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
returnImage = filledImage; 

CGImageRelease(cgImage); 

如果你要堅持你的實現,我至少建議改變你提取您的UIImage使用原始圖像的「規模」,不要與CIFilter規模相混淆的方式。

UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:fromImage.scale orientation:fromImage.imageOrientation]; 
0

問題是僅縮放

簡單地做:

let result = UIImage(cgImage: cgimgresult!, scale: (originalImageView.image?.scale)!, orientation: (originalImageView.image?.imageOrientation)!) 
      originalImageView.image = result