详解minigui图片加载及显示

本文基于minigui3.0.12版本

一、接口方法

//加载图像内容bitmap到内存bmp句柄
int GUIAPI LoadBitmapFromFile (HDC hdc, PBITMAP bmp, const char* file_name)//释放bmp句柄
void GUIAPI UnloadBitmap (PBITMAP bmp)//加载bitmap到framebuffer;
BOOL GUIAPI FillBoxWithBitmap (HDC hdc, int x, int y, int w, int h,
                const BITMAP *bmp);

使用方式

PBITMAP bg_bmp = NULL; //新建一个bitmap句柄
bg_bmp = (PBITMAP)malloc(sizeof(BITMAP)); //为句柄分配存储空间
LoadBitmapFromFile(HDC_HANDLER, bg_bmp,"filename.png"); //加载图像像素到bitmap
FillBoxWithBitmap (HDC_HANDLER,0,0,100,100,bg_bmp); //绘制到(0,0,100,100)的位置,改接口带缩放功能
UnloadBitmap (bg_bmp);//释放bitmap空间

二、内部详细代码流程

2.1、解码过程

LoadBitmapFromFile
 get_extension(file_name) //获取图片文件后缀名
  MGUI_RWFromFile(file_name, "rb") //打开文件保存fp,保存读写方法fops到MG_RWops
   LoadBitmapEx(hdc, bmp, area, ext); //开始解码并根据fb像素格式保存转换后的像素内容到bmp

获得图片的fp、后缀名、以及读写文件的方法函数接下来继续分析LoadBitmapEx 在这里会根据图片的像素格式解码为对应的rgb格式的数据比如ARGB8888或者RGB888等格式后再转换为屏幕fb的像素格式最后存储到bitmap以方便后面进行读取显示。
不同的图片有不同的解码函数保存在

BITMAP_TYPE_INFO bitmap_types [MAX_BITMAP_TYPES] =
{
 { "gif", __mg_init_gif, __mg_load_gif, __mg_cleanup_gif, NULL, __mg_check_gif },
 { "png", __mg_init_png, __mg_load_png, __mg_cleanup_png, NULL, __mg_check_png },
}
LoadBitmapEx
 LOAD_BITMAP_INFO info;
 info.hdc = hdc;
 info.bmp = bmp; //将bmp存放到bitmap info
  LOAD_MYBITMAP_INFO* load_info;
  load_info = InitMyBitmapSL(area, ext, &my_bmp, pal); //将解码函数方法放到load_info中
     type = get_image_type(ext) //获取后缀名对应的解码函数数组指针对应上面的bitmap_types 数组
     load_info->type_info = bitmap_types + type; //获取png图片的解码函数方法init load等
     load_info->type_info->init (area, my_bmp, pal); //png init方法读取文件头信息保存到load_info->init_info
     my_bmp->bits = malloc (my_bmp->pitch); //分配行长空间给中间存储bitmap结构mybitmap用以后续逐行读取解码后的图片像素内容
  init_bitmap_from_mybmp (hdc, bmp, &my_bmp, pal, TRUE); //为bitmap分配存储空间并分配alpha像素存储的空间
     pdc = dc_HDC2PDC (hdc); //获取设备绘制上下文
     bmp->bmBitsPerPixel = pdc->surface->format->BitsPerPixel; //根据屏幕fb定制bitmap的像素位数32 24等
     bmp->bmBytesPerPixel = pdc->surface->format->BytesPerPixel; //根据屏幕fb定制bitmap的像素字节数4,3等
     size = GAL_GetBoxSize (pdc->surface, my_bmp->w, my_bmp->h, &bmp->bmPitch); //根据屏幕fb及图片宽高来确定bitmap存储空间大小
     bmp->bmBits = malloc (alloc_all?size:bmp->bmPitch) //分配存储空间
     if (my_bmp->flags & MYBMP_ALPHA && my_bmp->depth == 32)
     bmp->bmAlphaMask = calloc(1, size); //分配存储alpha空间
  LoadMyBitmapSL (area, load_info, &my_bmp, cb_load_bitmap_sl, &info); //逐行解码并存储解码后数据到bitmap
  	 info->type_info->load (area, info->init_info, my_bmp, cb, context);//png解碼函數
  	 	__mg_load_png
  	 	 png_read_row(info->png_ptr, rp, NULL); //读取一行png解码后的数据
  	 	 if (cb && !p) cb(context, my_bmp, i); //调用回调cb_load_bitmap_sl
  	 cb_load_bitmap_sl(void* context, MYBITMAP* my_bmp, int y)
  	  compilergba_bitmap_sl (info->hdc, dst_bits, dst_alpha_mask, my_bmp); 
  	   pixel = GAL_MapRGBA (pdc->surface->format, rgb.r, rgb.g, rgb.b, rgb.a); //将像素放到int pixel
  	    dst = _mem_set_pixel (dst, bpp, pixel); //根据bpp放到bitmap里

2.2 显示过程

FillBoxWithBitmap (HDC hdc, int x, int y, int w, int h,  const BITMAP* bmp)
	_begin_fill_bitmap (hdc, x, y, w, h, bmp, &fill_info); //计算填充区域信息
	_fill_bitmap (pdc, bmp, &fill_info);
		_dc_fillbox_bmp_clip (pdc, &fill_info->dst_rect, (BITMAP*)bmp); //不缩放的情况下调用该函数
			GAL_PutBox (pdc->surface, rect, bmp); //开始填充
				GAL_IntersectRect //计算重叠的填充区域 仅计算重绘的区域
				dstrow = (Uint8 *)dst->pixels + my_dstrect.y * dst->pitch + my_dstrect.x * dst->format->BytesPerPixel; //目的framebuffer
    			srcrow = (Uint8 *)box->bmBits + off_y * box->bmPitch + off_x * box->bmBytesPerPixel; //源bitmap
				_PutBoxAlpha (dst, dstrow, srcrow, w, h, box); //根据h高度一行行进行拷贝采用DUFFS_LOOP8拷贝
	_end_fill_bitmap (pdc, bmp, &fill_info); //拷贝完成后更新到真实framebuffer进行显示
		__mg_leave_drawing (pdc);
			kernel_ShowCursorForGDI (TRUE, pdc);
				GAL_UpdateRect (cur_pdc->surface, prc->left, prc->top, RECTWP(prc), RECTHP(prc)); //调用硬件tde 进行局部更新。

如果一开始就给了真实的framebuffer那后面的局部区域更新就不用调用了。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值