CIFilter guassianBlur и boxBlur уменьшают изображение - как избежать изменения размера?
я делаю снимок содержимого NSView
, применяя CIFilter
, и размещение результата обратно в представление. Если CIFilter
является формой размытия, например CIBoxBlur
или CIGuassianBlur
, отфильтрованный результат немного меньше, чем оригинал. Поскольку я делаю это итеративно, результат становится все более маленьким, чего я хочу избежать.
этот вопрос упоминается здесь хотя и в несколько ином контексте (Quartz Composer). Яблоко!--6--> демо приложения применяет Guassian blur
без сжатия изображения, но я еще не понял, как это приложение делает это (кажется, использует OpenGL
С которым я не знаком).
вот соответствующая часть кода (внутри NSView
подкласс)
NSImage* background = [[NSImage alloc] initWithData:[self dataWithPDFInsideRect:[self bounds]]];
CIContext* context = [[NSGraphicsContext currentContext] CIContext];
CIImage* ciImage = [background ciImage];
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"
keysAndValues: kCIInputImageKey, ciImage,
@"inputRadius", [NSNumber numberWithFloat:10.0], nil];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
CGImageRef cgImage = [context createCGImage:result
fromRect:[result extent]];
NSImage* newBackground = [[NSImage alloc] initWithCGImage:cgImage size:background.size];
если я попробую фильтр изменения цвета, такой как CISepiaTone
, который не сдвигает пиксели вокруг, сжатие не происходит.
мне интересно, есть ли быстрое решение, которое не включает погружение в openGL
?
3 ответов
они на самом деле не сжимают изображение, они расширяют его (я думаю, на 7 пикселей по всем краям), и по умолчанию UIView "масштаб для просмотра" делает его похожим на сжатие.
обрезать CIImage с:
CIImage *cropped=[output imageByCroppingToRect:CGRectMake(0, 0, view.bounds.size.width*scale, view.bounds.size.height*scale)];
где view-исходные границы вашего NSView, которые вы нарисовали, а "масштаб" - ваш [uiscreen mainScreen] масштаб].
вы, вероятно, хотите зажать изображение перед использованием размытия:
- (CIImage*)imageByClampingToExtent {
CIFilter *clamp = [CIFilter filterWithName:@"CIAffineClamp"];
[clamp setValue:[NSAffineTransform transform] forKey:@"inputTransform"];
[clamp setValue:self forKey:@"inputImage"];
return [clamp valueForKey:@"outputImage"];
}
затем размыть, а затем обрезать до исходного экстента. Таким образом, вы получите непрозрачные края.
решение@BBC_Z является правильным.
хотя я считаю более элегантным обрезать не в соответствии с видом, а с изображением.
И вы можете отрезать бесполезные размытые края:
// Crop transparent edges from blur
resultImage = [resultImage imageByCroppingToRect:(CGRect){
.origin.x = blurRadius,
.origin.y = blurRadius,
.size.width = originalCIImage.extent.size.width - blurRadius*2,
.size.height = originalCIImage.extent.size.height - blurRadius*2
}];