I am simply trying to scale down a Tbitmap as quickly as possible in C++ Builder... I am still fairly new to C++ and some elements I simply don't understand..
I can scale using a simple copy with pixels[x][y] however it takes a long time to execute...
To speed up I tried copying the relevant pixel data to integer variables which yielded about a 100% speed gain however it's still too slow...
I have made some additional optimizations eliminating unneeded writes, however a faster method would be very helpful...
void scale_bmp(float scale)
{
int x = 0;
int y = 0;
int h = bitmap1->Height;
int w = bitmap1->Width;
int h2 = bitmap1->Height * scale;
int w2 = bitmap1->Width * scale;
int sx = 0;
int sy = 0;
bitmap3->Height = h2;
bitmap3->Width = w2;
bitmap3->Transparent = true;
//bitmap already loaded in mat
//scale copy bitmap in memory
for(y = 0; y < h; y++)
{
sy = y * scale;
for (x = 0; x < w; x++)
{
sx = x * scale;
bitmap3->Canvas->Pixels[sx][sy] = mat[x][y];
}
}
}
for (int y = 0; y < bitmap3->Height; y++)
for (int x = 0; x < bitmap3->Width; x++)
bitmap3->Canvas->Pixels[x][y] = mat[x/scale][y/scale];
I don't know TBitmaps, but I doubt simply assigning values to its Height and Width properties will change the size. You should probably use the SetHeight and SetWidth methods instead (and there could be more to it than that).
why is it 'slow' ? Are the images huge, or are you doing a ton of small ones?
if the images are huge, consider doing threading and subdivide .. do 1/4 of the image in each of 4 threads for example. If you have many images, maybe do each in its own thread the brute force way.
your graphics card can this faster. If you put an image on a rectangle and then just move the rectangle in and out it will scale for you, and there is probably a way to ask it to do the work for you. Many games use multiple copies of the same image pre-scaled and let the graphics card to the fine tuning for small moves and swaps images to higher / better quality as it gets closer to the camera.
It's slow because I am using the pixels[x][y] method... It has to go through windows API...
There are other ways but I don't know how to use them... One of them is scanline[y] ... I think there may be others... I was told scanline is 1000 times faster... I have seen some examples but they are over my head... I am still new to C++...
I have no idea how to do the rectangle idea you suggest... The images are not large, otherwise this function would be totally useless... Prescaling is just not what I'm looking to do in this case.. The above code is almost fast enough but faster would be better...
Faster than what? Obviously that's not faster than my code. My code only writes once to each destination pixel. Your's writes multiple times. (This is assuming you are making the image smaller.)
Anyway, you seem to know almost nothing about the graphics system you are using. Of course there are methods for setting the size. It turns out that the public method is called SetSize(). There are resize methods and everything you would need to do this properly (such as TCanvas::StretchDraw).
Faster than what? Obviously that's not faster than my code. My code only writes once to each destination pixel.
Faster than the code in the first post.....
Actually it probably is faster than your edit thanks... It not only writes once per destination pixel but it doesn't write when the color already exists on the canvas. So it's adaptive based on the source graphic... [x/scale] trips an "illegal use of float" which is why I did the x * scale ...
In anycase SetSize() [found that] but it doesn't scale anything. StretchDraw does exist but I don't know how it applies to shrinking the graphic, but I'll look again...
Thanks, I have seen a couple of examples ... I am new to c++ and I wasn't really clear on how to use that method... (felt like my head was going to explode) I will go back at some point and look again at these other methods...
The code I have now works pretty well, but I would like some free overhead to allow for doing other things with the cpu cycles...