Saving Bitmaps
Scooter

Hi all:
I posted this same thing before but nobody understood what I wanted.
I would like to try again so here goes:

I have an ALLEGRO_BITMAP *image. I want to rotate that image 45 degrees.
No problem! How on this earth do I save that rotated bitmap (image) so
I can use it later in my program? If later I call that bitmap (image)
I get the bitmap before it was rotated. I want the bitmap after it was
rotated.

I tried this:

al_save_bitmap("temp.png", image);
temp_image = al_load_bitmap("temp.png");

It does NOT work! temp_image shows the image BEFORE ROTATION.
This is a big problem for me and it comes up all the time.
Hopefully someone can help me. We had this discussion before and they
did try to help but didn't understand what I wanted,

Thanks guys!!!!!!!!!!

torhu

You probably saved the wrong bitmap, then? It's easier to help if you post your actual code ;)

DanielH

You can't save a rotated bitmap. You can DRAW your rotated bitmap onto another rectangular bitmap and then save that.

Dizzy Egg

Original rotation confusion...

This code will do exactly what you want. Attached are the original image and rotated image after saving.

#SelectExpand
1 2#define _USE_MATH_DEFINES 3 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_image.h> 6#include <math.h> 7 8#define DEG_TO_RAD(deg) (deg*M_PI/180.0) 9 10int main() 11{ 12 al_init(); 13 al_init_image_addon(); 14 15 al_set_new_display_flags(ALLEGRO_WINDOWED); 16 ALLEGRO_DISPLAY* display = al_create_display(1280, 720); 17 18 //Load the test image 19 ALLEGRO_BITMAP* image = al_load_bitmap("test_image.png"); 20 21 //Get the test image width/height 22 int image_w = al_get_bitmap_width(image); 23 int image_h = al_get_bitmap_height(image); 24 25 //Work out the largest dimenstion (width or height) 26 int image_largest_size = image_w > image_h ? image_w : image_h; 27 28 //Create a new bitmap with the largest dimension for width height (to fit out rotated image) 29 ALLEGRO_BITMAP* rotated_image = al_create_bitmap(image_largest_size, image_largest_size); 30 31 //Set the new bitmap as target 32 al_set_target_bitmap(rotated_image); 33 34 //Draw the test image rotated by 45 degrees 35 al_draw_rotated_bitmap(image, image_w / 2, image_h / 2, image_largest_size / 2, image_largest_size / 2, DEG_TO_RAD(45), 0); 36 37 //Set the display as target 38 al_set_target_backbuffer(display); 39 40 //Save the rotated image 41 al_save_bitmap("rotated_image_saved.png", rotated_image); 42 43 //Cleanup 44 al_destroy_bitmap(image); 45 al_destroy_bitmap(rotated_image); 46 al_destroy_display(display); 47}

EDIT: Fixed to use proper 45 degree (radians) angle.

Scooter

Hi Dizzy:
Thanks! That did it:
This was a great learning exercise for me.
Now I know more about how to use the backbuffer in allegro5.
Thanks again, have a great day!

Dizzy Egg

EDIT: deleted drunk post.

Here's an updated version that will work with non-square images:

#SelectExpand
1 2#define _USE_MATH_DEFINES 3 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_image.h> 6#include <math.h> 7 8#define DEG_TO_RAD(deg) (deg*M_PI/180.0) 9 10struct size 11{ 12 int width; 13 int height; 14}; 15 16size get_rotated_image_size(int orig_width, int orig_height, int degrees); 17 18int main() 19{ 20 al_init(); 21 al_init_image_addon(); 22 23 al_set_new_display_flags(ALLEGRO_WINDOWED); 24 ALLEGRO_DISPLAY* display = al_create_display(1280, 720); 25 26 //Load the test image 27 ALLEGRO_BITMAP* image = al_load_bitmap("test_image.png"); 28 29 //Get the test image width/height 30 int image_w = al_get_bitmap_width(image); 31 int image_h = al_get_bitmap_height(image); 32 33 //Work out the largest dimenstion (width or height) 34 int image_largest_size = image_w > image_h ? image_w : image_h; 35 36 //Set rotation 37 int degrees = 45; 38 39 size rotated_image_size = get_rotated_image_size(image_w, image_h, degrees); 40 41 //Create a new bitmap with the largest dimension for width height (to fit out rotated image) 42 ALLEGRO_BITMAP* rotated_image = al_create_bitmap(rotated_image_size.width, rotated_image_size.height); 43 44 //Set the new bitmap as target 45 al_set_target_bitmap(rotated_image); 46 47 //Draw the test image rotated by 45 degrees 48 al_draw_rotated_bitmap(image, image_w / 2, image_h / 2, rotated_image_size.width / 2, rotated_image_size.height / 2, DEG_TO_RAD(degrees), 0); 49 50 //Set the display as target 51 al_set_target_backbuffer(display); 52 53 //Save the rotated image 54 al_save_bitmap("rotated_image_saved.png", rotated_image); 55 56 //Cleanup 57 al_destroy_bitmap(image); 58 al_destroy_bitmap(rotated_image); 59 al_destroy_display(display); 60} 61 62size get_rotated_image_size(int orig_width, int orig_height, int degrees) { 63 degrees = degrees % 180; 64 65 if (degrees < 0) { 66 degrees = 180 + degrees; 67 } 68 if (degrees >= 90) { 69 int copy_orig_height = orig_height; 70 orig_height = orig_width; 71 orig_width = copy_orig_height; 72 degrees = degrees - 90; 73 } 74 if (degrees == 0) { 75 size new_image_size; 76 new_image_size.width = orig_width; 77 new_image_size.height = orig_height; 78 return new_image_size; 79 } 80 81 float radians = DEG_TO_RAD(degrees); 82 int width = ceil((orig_width * cos(radians)) + (orig_height * sin(radians))); 83 int height = ceil((orig_width * sin(radians)) + (orig_height * cos(radians))); 84 85 size new_image_size; 86 new_image_size.width = width; 87 new_image_size.height = height; 88 return new_image_size; 89}

Edgar Reynaldo

Drawing only affects the target bitmap. So target a buffer that's big enough, draw your rotated bitmap onto it, and then save the buffer.

Thread #618878. Printed from Allegro.cc