将位图图像加载到特定大小

3

我正在尝试使用 Allegro 将位图加载到特定大小。

al_create_bitmap(x, y) - 创建一个指定大小的位图

al_load_bitmap(filename) - 加载所需的图像,但仅以其原始大小加载。

我需要将位图加载到我设置的大小。有什么建议吗?

谢谢, Sonny

1个回答

2
关键是al_draw_scaled_bitmap()。使用它,您可以在任何新大小的目标位图上将任何源位图贴上。因此,您实际上可能不需要创建新位图。您始终可以使用该函数以不同的大小绘制位图。 Allegro 5具有硬件加速功能,因此这些类型的操作通常是“免费”的。
直接回答问题:
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;      
}

我在代码中注释了基本步骤。请记住,Allegro 5有一个隐含的目标,通常是显示器的后备缓冲区。然而,正如上面的代码所示,如果需要进行位图到位图操作,则可以将目标位图定向到其他位图。

另一种方法是将目标位图移出函数:

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,非常感谢您提供的帮助,正是我需要的。不过有一点让我有些困惑。prev_target = al_get_target_bitmap(); 我不明白prev_target在做什么? - codingNightmares
Allegro有一个隐式目标位图,可以通过al_set_target_bitmap()设置。所有未来的绘图操作都将在该位图上执行。如果此函数没有恢复目标位图,则调用代码可能不会意识到目标已更改,并可能意外地继续在位图上绘制。通常在A5中,在调用函数之前您需要注意这一点,但我将其留在函数内部,以便它可以按原样使用。 - Matthew
@codingNightmares,我添加了第二个示例。主要观点是函数通常不应该具有诸如更改目标位图之类的副作用。因此,在第二个示例中,该函数只会绘制到当前目标。这种做法通常更适合A5的API。 - Matthew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接