Can ofImage resize with Nearest Neighbor?

Hello! :stuck_out_tongue:
I’m trying to do something with small png files with alpha channel and when I resize I get a weird white gradient colored border. I need to resize using Nearest neighbor so I get all that sharp edge pixelated goodness with alpha channels.
Is this posible? or should I find some other solution. :stuck_out_tongue:

Thanks again :stuck_out_tongue:

if you are using ofImage::resize, it seems it’s hardcoded to bicubic, in develop, ofImage.cpp line 1017:

  
  
convertedBmp = FreeImage_Rescale(bmp, newWidth, newHeight, FILTER_BICUBIC);  
  

you could hack the core, to add an interpolation method, like:

  
  
ofImage::resize(int w, int h, ofInterpolationMethod interp=OF_INTERPOLATE_BICUBIC)  
  

also ofPixels can actually resize using nearest neighbors so you can just do:

  
  
image.getPixelsRef().resize(w,h,OF_INTERPOLATE_NEAREST_NEIGHBOR);  
image.update();  
  

Thanks Arturo!
I think I’ll do the pixels method so I can still use bicubic on other images, but now I get this problem and I think I get it but I don’t know how to fix it properly:
Here’s the code that imports a 40x40 png file with alpha channel and tries to upscale to 240x240:

  
    ship.loadImage("Ship_0_Color.png");  
    ship.getPixelsRef().resize(240, 240, OF_INTERPOLATE_NEAREST_NEIGHBOR);  
    ship.update();  

and here is the error:
[tt]OF: OF_LOG_ERROR: ofTexture::loadData() failed to upload 240 x 240 data to 40
x 40 texture[/tt]

mmh, ok yes you need to do something like:

  
  
ofPixels pix;  
ofLoadImage(pix,"img.png");  
pix.resize(240,240,OF_INTERPOLATE_NEAREST_NEIGHBOR);  
ship.setFromPixels(pix);  
  

ahhhh :smiley: got it :stuck_out_tongue:
Thank you! :smiley:

I get this little error now. Is this what happens with the “Non power of 2” size textures?.
The error is that weird color line at the bottom of the ship.

Can anyone help me with this little glitch? :stuck_out_tongue:
or maybe point me to the openGL information that may fix this?

I don’t know the names or concepts about why this happens, that would be great to know too! :smiley:
Thanks!

it could be something in the resize function in ofPixels but i’ve used it without problem before. try saving it to an image after resizing the pixels with:

ofSaveImage(pixels,“image.png”);

and see if the glitch appears also in the image. I don’t think it’s related with non-power of 2 textures

Hello again!
Nope, doesnt work. I’ll try with some other sprites. Thank you. =)

Hello again.
I haven’t found a solution using ofPixels, but I had used a different method a long time ago to get pixelation as it should look. I’ll just mention it in case anyone has problems.

The trick is to use oversized pixelated png files with alpha channel. Meaning, open something like Photoshop, load your sprite, resize it to a larger image using a Resize function and setting it to use Nearest Neighbor Method.
You will get a very standard pixelated look while resizing in openF, either bigger or smaller. And this is really usefull for when the image resizing needs to be dynamic and pixelated, almost looking like a SNES pixelation. I bet there is a better method for achieving the look.

Anyways, thank you Arturo! I will still try to find whats wrong with my code here using your method. :stuck_out_tongue:

This is odd… the error is visually half the size of what it should be.
Say I make every pixel have a 40x40 size, the distortion is 20x20.
I’m investigating.

It looks like the last line is just random information in memory. The attached picture was made running the program in parallel three times, in order have the three instances allocated to different part of my RAM. (I guess RAM also has some data remanence).
As you can see, example 1 is very inconsistent, which would leave me to believe that color is been randomly read from some other part of the memory.
Example 2 is a bit more consistent but still fails.
I’m not a computer science person and would be very thankfull of your opinions. :smiley:

have you tried to do the resizing in an app that does nothing else? just to discard that the error is not somewhere else. Also if you resize and save to an image the image has the pixels too or it’s only when showing it in the screen?

Yes. I’m uploading the code right now. I made it using Code Blocks 10.05 32 bit in Windows 7 x64 PC, with of_preRelease_v007_win_cb.

The Attached image shows the final result of this idea. It was saved using the method you mentioned earlier and I composed it using Photoshop just to make it easier to see, but I changed no colors.

When I resize to an odd number, visually I get a furry white border around the “pixels” which is to be expected from the algorithm but it is not present in the exported png files which I found odd, so I added that to the attached image.

Another thing, when I compile something like this I get the binaries with a few dlls. One of them is FreeImage.dll. Is it possible that my FreeImage.dll is not up-to-date? I ask this because I remember in the old openF 0062 one had to add files to Code Blocks in order to get it to work. I may have not updated it since then, but I’ve never been told to do this with 007.

Also, don’t press ‘+’ or ‘-’ to much and too often, it most certainly will crash the app but not all the time. I guess it might be because of overloading on the “load_images()” or something. This happens only in this test because I made it to try stuff so it is not in the application that I am programming.

of_Resize_Nearest_Neighbor.zip

i’m still not sure what this bug is, but i want to add: unless you absolutely need the pixel data, you can do nearest neighbor resizing with opengl. just say:

  
  
ofSetMinMagFilters(GL_NEAREST, GL_NEAREST);  
  

and then when you say img.draw(x, y, w, h), it will use nearest neighbor interpolation.

if you want it to do NN on upscale, but bilinear on downscale, you can change the second flag to GL_LINEAR

Thanks Kyle, I will try this out now. =D

Thanks openF forum por your patience. :stuck_out_tongue:

This is odd, I get inconsistent resizing of images. I used this code inside the setup(), update() and draw() all together and separately and what I get after that is some textures use Nearest Neighbor and some don’t. I also tried making every image resize.
Anyways, I thought I should let you know of what I got but I’m going to use the old method I mentioned. Thank you guys for your time. =D

i think if you use ofSetMinMagFilters() just before drawing a texture, you should always be ok.

one of the issues you might have found is that ofTexture::allocate() resets the min/mag filters without telling you.

I did not know that.
Thanks again Kyle!

sorry to revive an old thread – but is there a way to change scaling algorithms in 2014? i tried the ofSetMinMagFilters immediately before image load and immediately before image draw to no avail.

you should do it per image like:

img.getTextureReference().setTextureMinMagFilter(GL_NEAREST,GL_NEAREST);
2 Likes