ぼかしをサポートする必要があるドキュメントによると、「iOS5.0以降で利用可能」に注意してください。
しかし、デバイスによると、それはしません:
[CIFilter filterNamesInCategory:kCICategoryBlur];
何も返しません。
以下によると、これらのフィルターのみが私のiPhoneとシミュレーター(どちらも5.0を実行しています)で使用できます。
[CIFilter filterNamesInCategory:kCICategoryBuiltIn]
CIAdditionCompositing,
CIAffineTransform,
CICheckerboardGenerator,
CIColorBlendMode,
CIColorBurnBlendMode,
CIColorControls,
CIColorCube,
CIColorDodgeBlendMode,
CIColorInvert,
CIColorMatrix,
CIColorMonochrome,
CIConstantColorGenerator,
CICrop,
CIDarkenBlendMode,
CIDifferenceBlendMode,
CIExclusionBlendMode,
CIExposureAdjust,
CIFalseColor,
CIGammaAdjust,
CIGaussianGradient,
CIHardLightBlendMode,
CIHighlightShadowAdjust,
CIHueAdjust,
CIHueBlendMode,
CILightenBlendMode,
CILinearGradient,
CILuminosityBlendMode,
CIMaximumCompositing,
CIMinimumCompositing,
CIMultiplyBlendMode,
CIMultiplyCompositing,
CIOverlayBlendMode,
CIRadialGradient,
CISaturationBlendMode,
CIScreenBlendMode,
CISepiaTone,
CISoftLightBlendMode,
CISourceAtopCompositing,
CISourceInCompositing,
CISourceOutCompositing,
CISourceOverCompositing,
CIStraightenFilter,
CIStripesGenerator,
CITemperatureAndTint,
CIToneCurve,
CIVibrance,
CIVignette,
CIWhitePointAdjust
残念ながら、ブラーはサポートされていません。そのためには、自分でロールする必要があります。
IOS5.0のCoreImageにはブラーフィルターがありませんが、GPUで高速化された画像とビデオのブラーを取得する方法はまだあります。私のオープンソース GPUImage フレームワークには、ガウス(一般的なガウスにはGPUImageGaussianBlurFilterを使用、ハードウェアに最適化された9ヒットガウスにはGPUImageFastBlurFilterを使用)、ボックス(GPUImageBoxBlurFilterを使用)、中央値(GPUImageBoxBlurFilterを使用)など、複数のブラータイプがあります。 GPUImageMedianFilterを使用)、およびバイラテラルブラー(GPUImageBilateralBlurFilterを使用)。
ハードウェアに最適化されたガウスぼかしを取り除くために使用されるシェーダーについて この回答 で説明します。フレームワーク内の残りの部分に使用するコードを調べることができます。これらのフィルターは、私がこれまで試したどのCPUバウンドルーチンよりも数十倍高速に実行されます。
また、これらのブラーを、アンシャープマスキング、チルトシフトフィルタリング、キャニーエッジ検出、ハリスコーナー検出などの多段階処理効果に組み込みました。これらはすべて、このフレームワーク内のフィルターとして使用できます。
繰り返しになりますが、iOSのぼかしの問題をすべて保存するために、私の貢献は次のとおりです。
https://github.com/tomsoft1/StackBluriOS
StackBlurに基づくシンプルなブラーライブラリ。スタックぼかしはガウスぼかしに非常に似ていますが、はるかに高速です( http://incubator.quasimondo.com/processing/fast_blur_deluxe.php を参照)
次のように使用します。
UIImage *newIma=[sourceIma stackBlur:radius]
この助けを願っています
私もiOSのCoreImageがぼかしをサポートしていないことに失望しました。これは、UIImageで9タップのガウスぼかしを実行するために作成した関数です。繰り返し呼び出すと、ぼやけが強くなります。
@interface UIImage (ImageBlur)
- (UIImage *)imageWithGaussianBlur9;
@end
@implementation UIImage (ImageBlur)
- (UIImage *)imageWithGaussianBlur9 {
float weight[5] = {0.2270270270, 0.1945945946, 0.1216216216, 0.0540540541, 0.0162162162};
// Blur horizontally
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[0]];
for (int x = 1; x < 5; ++x) {
[self drawInRect:CGRectMake(x, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[x]];
[self drawInRect:CGRectMake(-x, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[x]];
}
UIImage *horizBlurredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Blur vertically
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[horizBlurredImage drawInRect:CGRectMake(0, 0, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[0]];
for (int y = 1; y < 5; ++y) {
[horizBlurredImage drawInRect:CGRectMake(0, y, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[y]];
[horizBlurredImage drawInRect:CGRectMake(0, -y, self.size.width, self.size.height) blendMode:kCGBlendModePlusLighter alpha:weight[y]];
}
UIImage *blurredImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//
return blurredImage;
}
次のような既存の画像で呼び出すだけです。
UIImage *blurredImage = [originalImage imageWithGaussianBlur9];
次のように繰り返して、ぼかしを強くします。
blurredImage = [blurredImage imageWithGaussianBlur9];
更新:iOS6以降[CIFilter filterNamesInCategory:kCICategoryBlur];
はCIGaussianBlur
を返します。これは、このフィルターがデバイスで使用可能であることを意味します。これは事実ですが、GPUImageを使用すると、(おそらく)パフォーマンスと柔軟性が向上します。
これは、さまざまなアプローチでiOSアプリケーションにぼかし効果を作成するためのチュートリアルへのリンクです。 http://blog.denivip.ru/index.php/2013/01/blur-effect-in-ios-applications/?lang=en
IOSアプリでOpenGLESを使用できる場合、これは、選択したピクセル近傍半径の中央値を計算する方法です(もちろん、中央値は一種のぼかしです)。
kernel vec4 medianUnsharpKernel(sampler u) {
vec4 pixel = unpremultiply(sample(u, samplerCoord(u)));
vec2 xy = destCoord();
int radius = 3;
int bounds = (radius - 1) / 2;
vec4 sum = vec4(0.0);
for (int i = (0 - bounds); i <= bounds; i++)
{
for (int j = (0 - bounds); j <= bounds; j++ )
{
sum += unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j)))));
}
}
vec4 mean = vec4(sum / vec4(pow(float(radius), 2.0)));
float mean_avg = float(mean);
float comp_avg = 0.0;
vec4 comp = vec4(0.0);
vec4 median = mean;
for (int i = (0 - bounds); i <= bounds; i++)
{
for (int j = (0 - bounds); j <= bounds; j++ )
{
comp = unpremultiply(sample(u, samplerTransform(u, vec2(xy + vec2(i, j)))));
comp_avg = float(comp);
median = (comp_avg < mean_avg) ? max(median, comp) : median;
}
}
return premultiply(vec4(vec3(abs(pixel.rgb - median.rgb)), 1.0));
}
手順の簡単な説明1.3x3近傍のソースピクセルを囲むピクセルの値の平均を計算します。 2.平均よりも小さい同じ近傍内のすべてのピクセルの最大ピクセル値を見つけます。 3. [オプション]エッジ検出のソースピクセル値から中央値ピクセル値を減算します。
エッジ検出に中央値を使用している場合、より良い結果を得るために上記のコードを変更する方法がいくつかあります。つまり、ハイブリッド中央値フィルタリングと切り捨てられたメディアフィルタリング(代替およびより良い「モード」フィルタリング)です。興味のある方はお問い合わせください。
Xamarinを使用しているため、John Stephenの回答をC#に変換しました。
private UIImage ImageWithGaussianBlur9(UIImage image)
{
var weight = new nfloat[]
{
0.2270270270f, 0.1945945946f, 0.1216216216f, 0.0540540541f, 0.0162162162f
};
var width = image.Size.Width;
var height = image.Size.Height;
// Blur horizontally
UIGraphics.BeginImageContextWithOptions(image.Size, false, 1f);
image.Draw(new CGRect(0f, 0f, width, height), CGBlendMode.PlusLighter, weight[0]);
for (int x = 1; x < 5; ++x)
{
image.Draw(new CGRect(x, 0, width, height), CGBlendMode.PlusLighter, weight[x]);
image.Draw(new CGRect(-x, 0, width, height), CGBlendMode.PlusLighter, weight[x]);
}
var horizBlurredImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
// Blur vertically
UIGraphics.BeginImageContextWithOptions(image.Size, false, 1f);
horizBlurredImage.Draw(new CGRect(0, 0, width, height), CGBlendMode.PlusLighter, weight[0]);
for (int y = 1; y < 5; ++y)
{
horizBlurredImage.Draw(new CGRect(0, y, width, height), CGBlendMode.PlusLighter, weight[y]);
horizBlurredImage.Draw(new CGRect(0, -y, width, height), CGBlendMode.PlusLighter, weight[y]);
}
var blurredImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return blurredImage;
}