19

画像を撮って、比較的速く(たとえば0.1秒で)ぼかしたいです。画像サイズが256x256pxを超えることはほとんどありません。

すべてのピクセルをループして隣接するピクセルと平均化する必要がありますか、それともこれを行うためのより高いレベルの方法がありますか?

PS:複数のボックスぼかしがガウスぼかしに近似する可能性があることを認識しています。

4

7 に答える 7

36

iOS3.2以降のアプリ向けの非常に高速でかなりくだらない方法を見つけました

  UIView *myView = [self view];
  CALayer *layer = [myView layer];
  [layer setRasterizationScale:0.25];
  [layer setShouldRasterize:YES];

これにより、ビューが 4x4 ピクセルのチャンクにラスタライズされ、バイリニア フィルタリングを使用してスケールアップされます。非常に高速で、モーダル ビューで背景ビューをぼかしたいだけの場合は問題ありません。

元に戻すには、ラスタ化スケールを 1.0 に戻すか、ラスタ化をオフにします。

于 2010-11-22T21:12:00.867 に答える
5

how-do-i-create-blurred-text-in-an-iphone-viewから

AppleのGLImageProcessingiPhoneサンプルをご覧ください。とりわけ、それはいくつかのぼかしを行います。

関連するコードは次のとおりです。

static void blur(V2fT2f *quad, float t) // t = 1
{
    GLint tex;
    V2fT2f tmpquad[4];
    float offw = t / Input.wide;
    float offh = t / Input.high;
    int i;

    glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);

    // Three pass small blur, using rotated pattern to sample 17 texels:
    //
    // .\/.. 
    // ./\\/ 
    // \/X/\   rotated samples filter across texel corners
    // /\\/. 
    // ../\. 

    // Pass one: center nearest sample
    glVertexPointer  (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x);
    glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glColor4f(1.0/5, 1.0/5, 1.0/5, 1.0);
    validateTexEnv();
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    // Pass two: accumulate two rotated linear samples
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    for (i = 0; i < 4; i++)
    {
        tmpquad[i].x = quad[i].s + 1.5 * offw;
        tmpquad[i].y = quad[i].t + 0.5 * offh;
        tmpquad[i].s = quad[i].s - 1.5 * offw;
        tmpquad[i].t = quad[i].t - 0.5 * offh;
    }
    glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].x);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glActiveTexture(GL_TEXTURE1);
    glEnable(GL_TEXTURE_2D);
    glClientActiveTexture(GL_TEXTURE1);
    glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].s);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_INTERPOLATE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_TEXTURE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PREVIOUS);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,         GL_PRIMARY_COLOR);
    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,     GL_SRC_COLOR);
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_PRIMARY_COLOR);

    glColor4f(0.5, 0.5, 0.5, 2.0/5);
    validateTexEnv();
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    // Pass three: accumulate two rotated linear samples
    for (i = 0; i < 4; i++)
    {
        tmpquad[i].x = quad[i].s - 0.5 * offw;
        tmpquad[i].y = quad[i].t + 1.5 * offh;
        tmpquad[i].s = quad[i].s + 0.5 * offw;
        tmpquad[i].t = quad[i].t - 1.5 * offh;
    }
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    // Restore state
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glClientActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, Half.texID);
    glDisable(GL_TEXTURE_2D);
    glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,     GL_SRC_ALPHA);
    glActiveTexture(GL_TEXTURE0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glDisable(GL_BLEND);
}
于 2009-08-10T18:49:14.137 に答える
4

常にまたは少なくとも頻繁に同じブラー設定を使用する場合は、空間ドメインではなく周波数ドメインでフィルタリングを実行することで速度を上げることができます。

  1. 2Dガウス分布であるフィルター画像G(u、v)を事前に準備します
  2. 入力画像にフーリエ変換を適用しますf(x、y)-> F(u、v)
  3. 乗算によるフィルタリング:H(u、v)= F(u、v)。* G(u、v)(行列乗算ではなく、ピクセル単位の乗算)
  4. 逆フーリエ変換により、フィルター処理された画像を空間領域に変換し直します。H(u、v)-> h(x、y)

このアプローチの長所は、近隣の平均化と比較して、ピクセル単位の乗算がかなり高速である必要があることです。したがって、多くの画像を処理する場合、これが役立つ場合があります。

欠点は、iPhoneでフーリエ変換をどれだけ速く実行できるかわからないため、他の実装よりもはるかに遅い可能性があることです。

それ以外は、iPhoneはOpenGLをサポートしているので、テクスチャリング機能/描画を使用してそれを行うことができると思います。申し訳ありませんが、私はOpenGLの専門家ではなく、その方法について実際的なアドバイスをすることはできません。

于 2009-07-17T08:57:19.347 に答える
3

貧乏人のぼかしのための2つのトリックはここにあります:

  1. 画像を取得し、部分的な不透明度で5回または6回(または必要な回数だけ)描画します。そのたびに、異なる方向に2、3ピクセルオフセットします。より多くの方向により多くの時間を描画すると、より良いぼかしが得られますが、処理時間は明らかにトレードオフになります。これは、半径が比較的小さいブラーが必要な場合に適しています。

  2. 単色画像の場合、実際にはビルドインシャドウを単純なぼかしとして使用できます。

于 2009-07-16T20:59:38.293 に答える
1

openGLを介してピクセルレベルで画像を変更するアルゴリズムは、少し遅くなります。openGLテクスチャをピクセルごとに操作し、フレームごとに更新すると、残念ながらパフォーマンスが不十分になります。

複雑なぼかしルーチンの実装に取り​​組む前に、テストリグの作成とピクセル操作の実験に時間を費やしてください。

于 2009-07-20T09:40:52.243 に答える
0

ぼかしの非常に基本的な (またはもっと柔らかくする) 方法は、隣接する 2 つのピクセルを平均し、その平均を両方のピクセルに適用することです。これを画像全体で繰り返すと、わずかにぼやけます (柔らかくなります)。

于 2010-11-20T13:15:11.453 に答える