6

フィルターを使用していくつかのテストを行っていますCIPixellateが、機能していますが、結果の画像のサイズは異なります。inputscale を変更しているので、これは理にかなっていると思いますが、期待していたものではありませんでした。画像の rect 内でスケーリングすると思っていました。

誤解/フィルターの使用が間違っているのでしょうか、それとも出力画像を必要なサイズにトリミングする必要があるのでしょうか。

また、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;
}
4

3 に答える 3

1

問題はスケーリングのみです。

単に行う:

let result = UIImage(cgImage: cgimgresult!, scale: (originalImageView.image?.scale)!, orientation: (originalImageView.image?.imageOrientation)!)
            originalImageView.image = result
于 2017-09-03T18:45:43.057 に答える
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);

実装に固執する場合は、CIFilter スケールと混同しないように、少なくとも元の画像の「スケール」を使用するように UIImage を抽出する方法を変更することをお勧めします。

UIImage *newImage = [UIImage imageWithCGImage:cgiimage scale:fromImage.scale orientation:fromImage.imageOrientation];
于 2015-04-22T03:37:52.243 に答える