Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad blur/distortion of small images when filtering #1212

Closed
ghost opened this issue Sep 24, 2013 · 3 comments
Closed

Bad blur/distortion of small images when filtering #1212

ghost opened this issue Sep 24, 2013 · 3 comments

Comments

@ghost
Copy link

ghost commented Sep 24, 2013

I am processing small images 8x8 pixels, I am scaling the images in this test case to 320x320 and I am getting bad distortion on the output image.

I chose 320x320 as the output size for the test, as I get exactly the same distortion when viewing the 8x8 image in the iPhone photo app.

This suggests that the issue might be where GPUImage is using core image, possible to force the output size?

Is there any known solution for this issue?

Here is the code:

UIImage *inputImage = [UIImage imageNamed:@"8x8.png"];

sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage];

transformFilter = [[GPUImageTransformFilter alloc] init];
//transformFilter.affineTransform = CGAffineTransformMakeScale(2.0, 2.0);
[transformFilter forceProcessingAtSize:CGSizeMake(320.0, 320.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;
}

Here is the original 8x8 image:

8x8

Here is what is looks like zoomed in:

inputimage

Here is what the 320x320 image output from the filter chain above looks like.

filtered1

@BradLarson
Copy link
Owner

What you're seeing is due to linear interpolation. By default, the texture sampling magnification filter I use is GL_LINEAR. This means that when upsampling a smaller image, you see the above style of linear interpolation instead of hard edges.

You should be able to change this behavior by setting the magFilter and minFilter options on your GPUImagePicture (and any filters that do upsampling after that) to GL_NEAREST immediately after initialization. I know with a filter you have to do this before you add it as a target for a source, but I'm not sure if this will work properly with a GPUImagePicture instance if done right after initialization. The GPUImagePicture class may need to be extended to support these magnification filter options, or you could use a dummy filter after the picture that doesn't upsample, set the magnification options on that, and then use a filter after that to upsample properly.

@ghost
Copy link
Author

ghost commented Sep 25, 2013

Brad thanks for the pointer, I have created a custom version of GPUImagePicture and in initWithCGImage changed:

if (self.shouldSmoothlyScaleOutput)
        {
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        }

to:

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);
        }

@ghost ghost closed this as completed Sep 25, 2013
@BradLarson
Copy link
Owner

In the future, we might want to look into a way to have GPUImagePicture be able to act on parameter changes like this without having to customize the class. We'd need to somehow deal with the fact that the texture for the picture is created in in the initialization. Maybe rebinding the texture and resetting the texture min / mag options might be the way to go to support these settings changes after initialization.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant