3

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

codingNightmares
  • 313
  • 2
  • 9
  • 19

1 Answers1

2

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.
Matthew
  • 47,584
  • 11
  • 86
  • 98
  • Matthew thank you for this, exactly what I need. Although Im a little confused on a part. prev_target = al_get_target_bitmap(); I dont understand what pre_target is doing? – codingNightmares Feb 24 '13 at 18:17
  • Allegro has an implicit target bitmap that is set via al_set_target_bitmap(). All future drawing operations will be done to that bitmap. If this function didn't restore the target bitmap, then the calling code might not realize the target has been changed, and may accidentally continue to draw on the bitmap. Normally in A5, you would take care of this prior to calling the function, but I left it inside the function so that it could be used as-is. – Matthew Feb 24 '13 at 19:03
  • @codingNightmares, I added a second example. Main point is a function should not typically have side effects such as changing the target bitmap. So in the second example, the function just draws to the current target. That practice generally fits better with A5's API. – Matthew Feb 24 '13 at 19:10