Jump to content
  • Advertisement
Sign in to follow this  
jeff8j

c++ image resize rgba data

This topic is 2133 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I cant seem to figure out a way to rezise my rgba data I have tried searching online and learning how the bicubic interpolation works but I simply dont understand any of it and others say let the gpu do it but I dont want the requirement of opengl for servers.

 

Can someone point me to a nice tutorial or some code that can help me resize my image data

I have a rgba char* its size int with int height so my current function looks like 

void resize(char* data, int curwidth, int curheight, int width, int height);

Looks are not important it can be blocky or whatever the simplest solution will do

Thanks

Edited by jeff8j

Share this post


Link to post
Share on other sites
Advertisement

To help give a better answer, why are you asking?

 

If you are asking so you can learn the math, that is one thing.  If you are asking so you can process your images in game, that is something else.

 

 

The simplest solution is to simply farm the work out to another library that will do it.  The .net libraries can do it. Most graphics packages can do it.

 

In fact, most libraries offer better quality than simple bicubic interpolation. Some will even run fairly complex algorithms to help identify boundaries and ensure that important stuff remains important in the resized image. There are resizing algorithms that are better for growing or shrinking images, there are algorithms that tend to be better for line drawings, text, photographs, or pixel art.  Simply passing the right parameters to ImageMagick can give amazing results.

Edited by frob

Share this post


Link to post
Share on other sites

Well im kind of asking for general purpose but in this scenario right now I was just capturing a screenshot on a server without opengl and posting the screenshot to another site so I can access it.

 

Im not really worried about the quality to start off with I would just like to find something to get started with where I can learn from and get my little tool going all at once. Its c++ and linux so .net would not be prefered lol.

Share this post


Link to post
Share on other sites

Well im kind of asking for general purpose but in this scenario right now I was just capturing a screenshot on a server without opengl and posting the screenshot to another site so I can access it.

 

Im not really worried about the quality to start off with I would just like to find something to get started with where I can learn from and get my little tool going all at once. Its c++ and linux so .net would not be prefered lol.

 

In that case you probably already have ImageMagick installed.  Magick++ is easy to use as far as image libraries go.  If your image data is already in a good format, you could just do:

Image myImage( mydata );

myImage.resize( Geometry( xsize, ysize ) );

myImage.write( filename );

 

That is much easier than trying to implement your own bicubic filters.

Share this post


Link to post
Share on other sites

Looks good and probably the fastest way to get my tool going but I was hoping to learn it as well doesnt have to be bicubic just something that works lol.

Share this post


Link to post
Share on other sites
You're essentially asking for simplicity where there really isn't simplicity, you might as well be asking for simple cryptography. You could find "simple" cryptography but it won't actually be useful in a real scenario, a library like that is going to use a lot of math and intelligent filtering schemes to upscale or downscale images while attempting to retain the quality, it's not really anything mystical other than the proper usage of techniques.

In the same way you'd just end up making very poor quality resizing functions without devoting yourself to a lot of study and learning the techniques.

But really, why are you asking? Is there a possible reason you would need to roll your own code for resizing image data? Edited by Satharis

Share this post


Link to post
Share on other sites

Lol I didnt realize it was so complicated seems like it would be easy which is why I was wondering why I need a 500kb library to handle it. I guess then there is no reason to roll my own ill just use magick++. Thanks

Share this post


Link to post
Share on other sites

lol I didnt realize it was so complicated ...

Scaling an image can be seen as a 4 step process:

1. Enlarge the image in horizontal direction by an integer scale factor.

2. Enlarge the result of 1. in vertical direction, usually by the same factor as used in 1.

3. Downsize the result of 2. in vertical direction by another integer scale factor.

4. Downsize the result of 3. in vertical direction, usually by the same factor as used in 3.

 

If the enlarge factor is named n and the downsize factor is named m, then the overall factor is n over m. Obviously, any ( k * n ) / ( k * m ) with k being an integer (greater than 0) gives you the same result in the end, so you would use the smallest n, m as possible (for memory reasons).

 

Looking back at the 4 steps, the horizontal and vertical dimensions are handled separated. This "separation" is actually the term used in signal processing.

 

The enlarging steps result in more pixels than available before. This means that you have to generate pixel data where the original doesn't have one. So the way is to look at the local neighborhood of pixels and compute a pixel that fits in-between the neighborhood. This is called an interpolation. Not all pixels of a neighborhood should have the same influence onto the interpolated pixel; e.g. pixels that are farther away from the interpolation location should usually have less influence. So you have to put a weighting mask onto the neighborhood. The weighting is often done with a polynomial, and terms like "linear" or "cubic" tells you about the degree of the polynomial. Importantly, integrating over the weighting should result in 1.

 

BTW: A GPU does bi-linear interpolation. The "bi" in this term means that (a) it work in two dimensions and (b) is done separated. The "linear" means that the used polynomials is of degree 1, hence the neighborhood is just 2 by 2 pixels.

 

Interpolation can be understood as follows: Think of a series of equidistant, very thin peaks, each one meaning a pixel of the original image. Then pull at the ends so that the spacing of the original pixels gets evenly enlarged, so that the spacing is now n times the original. Think of the weighting function as a continuous overlay, whose zero point is put at the location where the interpolated pixels should be. Place the function with its axis at a interpolation location. The function now covers some of the pixels beneath (the said "neighborhood"). Multiply the covered pixel values with the value of the function, where you use the pixel location as the independent variable of the function, and sum up all the weighted pixels. Put this value as interpolated pixel at the zero location of the function (in another image buffer).

 

The downsizing steps result in less pixels than available before. The Nyquist–Shannon sampling theorem tells that dropping information may lead to aliasing. So you can't (or at least shouldn't) simply drop pixels. Instead, you have to apply a band-limiting filter (e.g. low-pass filter). There are many possibilities in doing so, e.g. digital filter design. However, such a filter again can be understood as a weighting function similar to the interpolation function described above. This time you place the filter function in sequence on top of every m-th pixel, do the weighting and summing (this is called "convolution" w.r.t. digital filters), and write the result into another image buffer. Formally, you then have to shrink the spacing in-between the decimated pixels by the factor of m.

 

Now, the above principle works but shows some problems in practice. E.g. if n/m has a long series of fractional digits, then the temporary image buffers to be used for interpolation are very large. One can join the interpolation and decimation functions into one, so being able to do the both steps of interpolation and decimation (per dimension) in a single step. Well, looking at the problem again, one sees that in this case a single scaling function would not be sufficient. This is because of the possible combinations of interpolation and decimation locations in the enlarged space. So you need to compute a full bank of weighting functions.

 

The above algorithm works fine if n/m is less than 1, but it will smooth images if n/m gets too great (whatever exactly this means ;)). There are some few algorithms that try to interpolate with edge retention, but that is a totally other chapter...

 

Hopefully I've given you an understandable overview of image scaling theory. Maybe the mentioned terms give you some hint to understand your original source better.

Edited by haegarr

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!