我希望能夠拍攝圖像並相對較快地進行模糊處理(比如在0.1秒內)。圖像尺寸幾乎不會大於256 x 256像素。如何在iPhone上實現一個方框或高斯模糊
我是否必須循環每個像素並將它們與鄰居平均,或者是否有更高級別的方法可以執行此操作?
PS:我知道多個框模糊可以接近高斯模糊。
我希望能夠拍攝圖像並相對較快地進行模糊處理(比如在0.1秒內)。圖像尺寸幾乎不會大於256 x 256像素。如何在iPhone上實現一個方框或高斯模糊
我是否必須循環每個像素並將它們與鄰居平均,或者是否有更高級別的方法可以執行此操作?
PS:我知道多個框模糊可以接近高斯模糊。
您可能想看看Mario Klingemann的StakBlur算法。它不是高斯,但非常接近。
如果你總是或至少經常使用你可能會做在頻域而不是空間域濾波獲得速度相同的模糊設置。
這種方法的優點是像素乘數與平均鄰域相比,這應該是相當快的。所以如果你處理很多圖像,這可能會有所幫助。
不利的一面是,我不知道你能在iPhone上執行傅里葉變換的速度有多快,所以這可能比其他實現要慢得多。
除此之外,我想因爲iPhone有OpenGL支持,你可以使用它的紋理函數/繪圖來做到這一點。很抱歉地說,雖然我不是OpenGL專家,但實際上並沒有給出任何實際建議。
任何通過openGL修改像素級圖像的算法都會慢一點;在OpenGL紋理上逐個像素地操作,然後在每一幀都進行更新,可悲的是性能不足。
花一些時間編寫測試裝置並嘗試執行像素操作,然後再執行復雜的模糊例程。
從how-do-i-create-blurred-text-in-an-iphone-view:
看看蘋果的GLImageProcessing iPhone樣本。除此之外,它的確有些模糊。
相關的代碼包括:
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);
}
的非常基本的模糊的(或也許更多一軟化的),就是平均2個相鄰像素和的平均值應用到兩個像素。在整個圖像中重複這一點,你會得到輕微的模糊(軟化)。
我發現了一個非常快非常糟糕的方式爲iOS3.2 +應用
UIView *myView = [self view];
CALayer *layer = [myView layer];
[layer setRasterizationScale:0.25];
[layer setShouldRasterize:YES];
此柵格化視圖到4×4像素塊,然後擴展它備份使用雙線性過濾...這是非常快速和長相好吧,如果你只是想在模態視圖下模糊背景視圖。
要撤消它,只需將柵格化比例設置回1.0或關閉柵格化。
我可以使用CGImageRef作爲StackBlur的輸入嗎?不知道我從哪裏得到像素數據。 – mahboudz 2009-08-11 08:15:39