Search code examples
imagebitmapallegroallegro5

loading a bitmap image to a certain size


Im trying to load a bitmap to a certain size using allegro.

al_crate_bitmap(x,y) - creates a bitmap to a certain size al_load_bitmap(filename) - loads the image i need, but to its original size.

I need to load a bitmap to a size I set. Any ideas?

Thanks, Sonny


Solution

  • The key is al_draw_scaled_bitmap(). With that, you can blit any source bitmap onto the target bitmap at any new size. So you may not actually need to create a new bitmap. You can always use that function to draw the bitmap at a different size. Allegro 5 is hardware accelerated, so these types of operations are often "free."

    To directly answer the question:

    ALLEGRO_BITMAP *load_bitmap_at_size(const char *filename, int w, int h)
    {
      ALLEGRO_BITMAP *resized_bmp, *loaded_bmp, *prev_target;
    
      // 1. create a temporary bitmap of size we want
      resized_bmp = al_create_bitmap(w, h);
      if (!resized_bmp) return NULL;
    
      // 2. load the bitmap at the original size
      loaded_bmp = al_load_bitmap(filename);
      if (!loaded_bmp)
      {
         al_destroy_bitmap(resized_bmp);
         return NULL;
      }
    
      // 3. set the target bitmap to the resized bmp
      prev_target = al_get_target_bitmap();
      al_set_target_bitmap(resized_bmp);
    
      // 4. copy the loaded bitmap to the resized bmp
      al_draw_scaled_bitmap(loaded_bmp,
         0, 0,                                // source origin
         al_get_bitmap_width(loaded_bmp),     // source width
         al_get_bitmap_height(loaded_bmp),    // source height
         0, 0,                                // target origin
         w, h,                                // target dimensions
         0                                    // flags
      );
    
      // 5. restore the previous target and clean up
      al_set_target_bitmap(prev_target);
      al_destroy_loaded_bmp(loaded_bmp);
    
      return resized_bmp;      
    }
    

    I've commented the basic steps in the code. Keep in mind that Allegro 5 has an implicit target that is usually the back buffer of the display. However, as the above code illustrates, you can target other bitmaps if you need to do bitmap to bitmap operations.

    Alternate way, moving the target bitmap outside the function:

    void load_bitmap_onto_target(const char *filename)
    {
      ALLEGRO_BITMAP *loaded_bmp;
      const int w = al_get_bitmap_width(al_get_target_bitmap());   
      const int h = al_get_bitmap_height(al_get_target_bitmap());
    
      // 1. load the bitmap at the original size
      loaded_bmp = al_load_bitmap(filename);
      if (!loaded_bmp) return;
    
      // 2. copy the loaded bitmap to the resized bmp
      al_draw_scaled_bitmap(loaded_bmp,
         0, 0,                                // source origin
         al_get_bitmap_width(loaded_bmp),     // source width
         al_get_bitmap_height(loaded_bmp),    // source height
         0, 0,                                // target origin
         w, h,                                // target dimensions
         0                                    // flags
      );
    
      // 3. cleanup
      al_destroy_bitmap(loaded_bmp);
    }
    
    ALLEGRO_BITMAP *my_bmp = al_create_bitmap(1000,1000);
    al_set_target_bitmap(my_bmp);
    load_bitmap_onto_target("test.png");
    // perhaps restore the target bitmap to the back buffer, or continue
    // to modify the my_bmp with more drawing operations.