使用OpenGL绘制的PNG图像周围的黑色边框

时间:2011-08-31 16:01:21

标签: iphone objective-c opengl-es

当我尝试使用OpenGL绘制具有透明度的PNG图像时,我周围会出现一个奇怪的黑色边框:

Two images with borders

但原始图像干净且正常:

Normal icons

我的代码:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

UIImage* allIcons = [[appDelegate load_image_from_zip: pl.icons[ico_index]] retain];

                CGRect rect = CGRectMake( 0, 0, allIcons.size.width/nIcons, allIcons.size.height );
                UIGraphicsBeginImageContext(rect.size);

                CGContextRef currentContext = UIGraphicsGetCurrentContext();

                CGContextTranslateCTM ( currentContext, 0, allIcons.size.height );
                CGContextScaleCTM ( currentContext, 1, -1 );

                CGRect clippedRect = CGRectMake(0, 0, rect.size.width, rect.size.height);
                CGContextClipToRect( currentContext, clippedRect);
                CGRect drawRect = CGRectMake(rect.origin.x * -1, rect.origin.y * -1, allIcons.size.width, allIcons.size.height);
                CGContextDrawImage(currentContext, drawRect, allIcons.CGImage);

4 个答案:

答案 0 :(得分:2)

这是可怕的预乘alpha问题。在搞清楚之前,我在这方面挣扎了好一周。告诉你的项目不压缩.png文件并不能解决问题,因为各种API调用会重新增加alpha。这就是我解决它的方式。

设置混合模式和颜色时:

blendFuncSource =  premultAlpha ? GL_ONE : GL_SRC_ALPHA;
blendFuncDestination = GL_ONE_MINUS_SRC_ALPHA;

if (premultAlpha)
{
    glColor4f(colorfilter.red*colorfilter.alpha, colorfilter.green*colorfilter.alpha, colorfilter.blue*colorfilter.alpha, colorfilter.alpha);
}
else
{
    glColor4f(colorfilter.red, colorfilter.green, colorfilter.blue, colorfilter.alpha);
}

你需要弄清楚你的图像是使用预乘的alpha。您可以在加载时检查png标题:

CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo( image );

...

switch( bitmapInfo & kCGBitmapAlphaInfoMask )
{
case kCGImageAlphaPremultipliedFirst:
    premultAlpha = YES;
    srcFormat = GL_BGRA;
    break;

case kCGImageAlphaFirst:
    srcFormat = GL_BGRA;
    break;

case kCGImageAlphaNoneSkipFirst:
    srcFormat = GL_BGRA;
    break;

default:
    srcFormat = GL_RGBA;
}

我在这里解释了很多代码,希望它仍然有用。

答案 1 :(得分:1)

假设您的TexEnv是默认GL_MODULEATE,请在绘制之前尝试glColor4ub(255, 255, 255, 255)

答案 2 :(得分:1)

问题在于您的图像具有预乘alpha,其中每个像素的颜色乘以其alpha值。 iPhone上的UIKit更喜欢预乘的alpha图像 - 混合它们的速度更快 - 但是OpenGL并没有假设,所以你的alpha通道的透明效果有点被应用两次,这导致你的图像中的半透明像素显得比他们实际上是。尝试关闭项目构建设置中的“压缩PNG文件”选项。

答案 3 :(得分:0)

试试这些

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);