Closed sdc-andy closed 2 years ago
Hi Andy, it looks like a bug on my side.
It seems as though all the foreground colours in the rotated image are correct but the white pixels in the background gets replaced with black pixels.
My money is on the alpha channel in the TGA having a value that is misinterpreted by library when it rotates the bitmap.
Can you perhaps provide a TGA file where the issue occurs but with the data you don't want me to see redacted so that I can take a look at what's going on?
I've manipulated the original image in Paint.net so that it just shows the same as the image above. Attached are the .tga source file and the resulting .bmp output file.
-Andy.
Thanks. I haven't had a chance to look at it yet, but I'll try to make some time tomorrow.
I know what the issue is:
The bm_rotate_blit()
function works like bm_maskedblit()
in that it compares each pixel on the source to the pen colour of the source bitmap and don't copy the pixels if they match.
Now, the bitmap created by bm_resample_blin()
has a white pen colour by default, and the bitmap from bm_create()
has a black background initially. So all the white pixels on the source bitmap are not copied and the black background shows through.
This matches the use case I had for it originally where I wanted to rotate graphics with transparent backgrounds, but I should've named the function bm_rotate_maskedblit()
instead and then have a bm_rotate_blit()
that behaves the same way bm_blit()
does.
I think for the next version I'm going to do precisely that. Also, if rotating bitmaps by 90 degrees is something that users require then I should add that.
In the meantime you can work around the issue by calling bm_set_color()
on resized
, like so:
Bitmap *resized = bm_resample_blin(in, NEW_WIDTH, NEW_HEIGHT);
bm_set_color(resized, 0x000000);
Here's a complete version of the program where it works:
#include <stdio.h>
#include "bmp.h"
#define NEW_WIDTH 640
#define NEW_HEIGHT 384
int main(int argc, char *argv[]) {
Bitmap *in = bm_load("test.tga");
Bitmap *resized = bm_resample_blin(in, NEW_WIDTH, NEW_HEIGHT);
bm_set_color(resized, 0x000000);
// Create a new bitmap to hold the rotated image hence NEW_WIDTH and NEW_HEIGHT reversed
Bitmap *rotated = bm_create(NEW_HEIGHT, NEW_WIDTH);
bm_rotate_blit(rotated, 0, 640, resized, 0, 0, 4.71239, 1);
bm_save(rotated, "out.bmp");
return 0;
}
I have pushed a couple of changes:
bm_rotate_blit()
to do what you expect
bm_rotate_maskedblit()
function that takes the mask colour into account for the other use-case.bm_rotate_cw()
and bm_rotate_ccw()
API functions to rotate a bitmap by 90° clockwise and counter-clockwise respectively to better handle your use-cases.You can now change your code as follows to achieve the desired effect:
// Bitmap *rotated = bm_create(NEW_HEIGHT, NEW_WIDTH);
// bm_rotate_blit(rotated, 0, 640, resized, 0, 0, 4.71239, 1);
Bitmap *rotated = bm_rotate_ccw(resized);
I am working with a .tga source file which has been generated by an external application which I am then resizing (from 800x480 to 640x384) and rotating using the bitmap library. In outline the code looks like:
The resizing process is working OK but when I perform the rotate operation the colours in the background:
Apologies for not being able to show the full image with all the corrupt colours but to do so would put information into the public domain which isn't yet allowed to be there.
The only option being passed on the command line when bmp.c is compiled is
-DBM_LAST_ERROR
.Do you know what I am missing or what I have done wrong?
-Andy.