我需要在图像通过 GPUImage 管道时对其进行缩放。我正在将图像输出到另一个文件。
这是我的简单管道:
UIImage *inputImage = [UIImage imageNamed:@"8x8.png"]; // The WID.jpg example is greater than 2048 pixels tall, so it fails on older devices
sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage];
transformFilter = [[GPUImageTransformFilter alloc] init];
transformFilter.affineTransform = CGAffineTransformMakeScale(2.0, 2.0);
[sourcePicture addTarget:transformFilter];
[transformFilter prepareForImageCapture];
[sourcePicture processImage];
UIImage *currentFilteredImage = [transformFilter imageFromCurrentlyProcessedOutput];
NSData *dataForPNGFile = UIImagePNGRepresentation(currentFilteredImage);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSError *error = nil;
if (![dataForPNGFile writeToFile:[documentsDirectory stringByAppendingPathComponent:@"filtered1.png"] options:NSAtomicWrite error:&error])
{
return;
}
输入图像是 8x8 像素,我想输出 16x16 像素的图像。
上述管道目前存在两个问题:
1)输出的图片尺寸还是8x8像素,虽然原图已经缩放了2.0,但是已经被裁剪回原来的尺寸了。
2) 输出图像模糊,这与我在 iPhone photo App 中查看非常小的图像时得到的效果相同。我认为它很可能是默认情况下在管道中某处应用的平滑函数。
我只想缩放输入图像而不进行任何平滑处理,以使像素保持清晰。
编辑:通过替换
transformFilter.affineTransform = CGAffineTransformMakeScale(2.0, 2.0);
和
[transformFilter forceProcessingAtSize:CGSizeMake(16.0, 16.0)];
我现在有一个 16x16 像素的缩放图像,但图像仍然模糊。
编辑2:
如果我将 8x8 图像缩放为 320x320,则结果与在 iPhone 照片应用程序中查看相同的 8x8 像素图像相同。它完全模糊,像素在像素边界处出现明亮的亮点。这表明问题不在于核心 GPUImage 代码,而在于 GPUImage 依赖于核心图像的功能。
有没有办法只使用 GPUImage 代码来扩展并完全避免核心图像?
编辑 3:我在 GPUImage github 项目上发布了失真问题,您可以在此处阅读完整的问题和回复
结果是我需要将 minFilter 和 magFilter 纹理参数设置为 GL_NEAREST 而不是 GL_LINEAR;
我的最终解决方案是克隆 GPUImagePicture 类并在 initWithCGImage: 选择器更改:
if (self.shouldSmoothlyScaleOutput)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
至:
if (self.shouldSmoothlyScaleOutput)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}