OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2855|回复: 3

小尺寸的BMP解码问题,alphabend这一项有什么用?

[复制链接]

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
发表于 2020-1-7 08:28:56 | 显示全部楼层 |阅读模式
8金钱
这函数有什么效果,P图吗,32位图特有的alphabend这一项有什么用?
我下了个图片转换器,将24位的转换为32位的BMP,用这个函数显示,跟stdbmp_decode一样,没什么特别的呀
u8 minibmp_decode(u8 *filename,u16 x,u16 y,u16 width,u16 height,u16 acolor,u8 mode)//尺寸小于240*320的bmp图片解码.
{
        FIL* f_bmp;
    u16 br;
        u8  color_byte;
        u16 tx,ty,color;         
        //tx,ty的实际坐标       
        u8 res;
        u16 i,j;
        u8 *databuf;                    //数据读取存                                                                       放地址
        u16 readlen=BMP_DBUF_SIZE;//一次从SD卡读取的字节数长度,不能小于LCD宽度*3!!!

        u8 *bmpbuf;                                  //数据解码地址
        u8 biCompression=0;                //记录压缩方式
       
        u16 rowcnt;                                //一次读取的行数
        u16 rowlen;                                   //水平方向字节数  
        u16 rowpix=0;                        //水平方向像素数          
        u8 rowadd;                                //每行填充字节数

        u16 tmp_color;

        u8 alphabend=0xff;                //代表透明色为0,完全不透明
        u8 alphamode=mode>>6;        //得到模式值,0/1/2
        BITMAPINFO *pbmp;           //临时指针                 
        //得到窗体尺寸
        picinfo.S_Height=height;
        picinfo.S_Width=width;
       


#if BMP_USE_MALLOC == 1        //使用malloc       
        databuf=(u8*)pic_memalloc(readlen);                //开辟readlen字节的内存区域
        if(databuf==NULL)return PIC_MEM_ERR;                //内存申请失败.
        f_bmp=(FIL *)pic_memalloc(sizeof(FIL));        //开辟FIL字节的内存区域
        if(f_bmp==NULL)                                                                //内存申请失败.
        {                 
                pic_memfree(databuf);
                return PIC_MEM_ERR;                               
        }          
#else
        databuf=bmpreadbuf;
        f_bmp=&f_bfile;
#endif
       
       
       
       
        res=f_open(f_bmp,(const TCHAR*)filename,FA_READ);//打开文件                                                           
        if(res==0)//打开成功.
        {
                f_read(f_bmp,databuf,sizeof(BITMAPINFO),(UINT*)&br);//读出BITMAPINFO信息
                pbmp=(BITMAPINFO*)databuf;                                        //得到BMP的头部信息   
                color_byte=pbmp->bmiHeader.biBitCount/8;        //彩色位 16/24/32  
                biCompression=pbmp->bmiHeader.biCompression;//压缩方式
                picinfo.ImgHeight=pbmp->bmiHeader.biHeight;        //得到图片高度
                picinfo.ImgWidth=pbmp->bmiHeader.biWidth;          //得到图片宽度
                //水平像素必须是4的倍数!!
                if((picinfo.ImgWidth*color_byte)%4)rowlen=((picinfo.ImgWidth*color_byte)/4+1)*4;
                else rowlen=picinfo.ImgWidth*color_byte;
               
                rowadd=rowlen-picinfo.ImgWidth*color_byte;        //每行填充字节数
                //开始解码BMP   
                color=0;//颜色清空                                                                                                                  
                tx=0 ;
                ty=picinfo.ImgHeight-1;
                if(picinfo.ImgWidth<=picinfo.S_Width&&picinfo.ImgHeight<=picinfo.S_Height)
                {                                 
                        x+=(picinfo.S_Width-picinfo.ImgWidth)/2;        //偏移到正中央
                        y+=(picinfo.S_Height-picinfo.ImgHeight)/2;        //偏移到正中央
                       
                        rowcnt=readlen/rowlen;                                                //一次读取的行数
                       
                        readlen=rowcnt*rowlen;                                                //一次读取的字节数
                       
                        rowpix=picinfo.ImgWidth;                                        //水平像素数就是宽度
                        f_lseek(f_bmp,pbmp->bmfHeader.bfOffBits);        //偏移到数据起始位置           
                        while(1)
                        {             
                                res=f_read(f_bmp,databuf,readlen,(UINT *)&br);        //读出readlen个字节
                                bmpbuf=databuf;                                                                        //数据首地址  
                                if(br!=readlen)rowcnt=br/rowlen;                                //最后剩下的行数
                                if(color_byte==3)                          //24位BMP图片
                                {
                                        for(j=0;j<rowcnt;j++)        //每次读到的行数
                                        {
                                                for(i=0;i<rowpix;i++)//写一行像素
                                                {
                                                        color=(*bmpbuf++)>>3;                                            //B
                                                        color+=((u16)(*bmpbuf++)<<3)&0X07E0;        //G
                                                        color+=(((u16)*bmpbuf++)<<8)&0XF800;        //R
                                                         pic_phy.draw_point(x+tx,y+ty,color);//显示图片       
                                                        tx++;
                                                }
                                                bmpbuf+=rowadd;//跳过填充区
                                                tx=0;
                                                ty--;
                                        }
                                }else if(color_byte==2)//16位BMP图片
                                {
                                        for(j=0;j<rowcnt;j++)//每次读到的行数
                                        {
                                                if(biCompression==BI_RGB)//RGB:5,5,5
                                                {
                                                        for(i=0;i<rowpix;i++)
                                                        {
                                                                color=((u16)*bmpbuf&0X1F);                        //R
                                                                color+=(((u16)*bmpbuf++)&0XE0)<<1;         //G
                                                                 color+=((u16)*bmpbuf++)<<9;              //R,G         
                                                            pic_phy.draw_point(x+tx,y+ty,color);//显示图片       
                                                                tx++;
                                                        }
                                                }else  //RGB 565
                                                {
                                                        for(i=0;i<rowpix;i++)
                                                        {                                                                                         
                                                                color=*bmpbuf++;                          //G,B
                                                                 color+=((u16)*bmpbuf++)<<8;        //R,G         
                                                                  pic_phy.draw_point(x+tx,y+ty,color);//显示图片       
                                                                tx++;
                                                        }
                                                }
                                                bmpbuf+=rowadd;//跳过填充区
                                                tx=0;
                                                ty--;
                                        }       
                                }else if(color_byte==4)                //32位BMP图片
                                {
                                        for(j=0;j<rowcnt;j++)        //每次读到的行数
                                        {
                                                for(i=0;i<rowpix;i++)
                                                {
                                                        color=(*bmpbuf++)>>3;                                            //B
                                                        color+=((u16)(*bmpbuf++)<<3)&0X07E0;        //G
                                                        color+=(((u16)*bmpbuf++)<<8)&0XF800;        //R
                                                        alphabend=*bmpbuf++;                                        //ALPHA通道
                                                        if(alphamode!=1) //需要读取底色
                                                        {
                                                                tmp_color=pic_phy.read_point(x+tx,y+ty);//读取颜色                  
                                                            if(alphamode==2)//需要附加的alphablend
                                                                {
                                                                        tmp_color=piclib_alpha_blend(tmp_color,acolor,mode&0X1F);        //与指定颜色进行blend                 
                                                                }
                                                                color=piclib_alpha_blend(tmp_color,color,alphabend/8);                         //和底色进行alphablend
                                                        }else tmp_color=piclib_alpha_blend(acolor,color,alphabend/8);                //与指定颜色进行blend
                                                        pic_phy.draw_point(x+tx,y+ty,color);//显示图片                                  
                                                        tx++;//x轴增加一个像素           
                                                }
                                                bmpbuf+=rowadd;//跳过填充区
                                                tx=0;
                                                ty--;
                                        }

                                }
                                if(br!=readlen||res)break;         
                        }         
                }       
                f_close(f_bmp);//关闭文件      
        }else res=PIC_SIZE_ERR;//图片尺寸错误       
       
                
#if BMP_USE_MALLOC == 1        //使用malloc       
        pic_memfree(databuf);         
        pic_memfree(f_bmp);                 
#endif       
        return res;
}            

最佳答案

查看完整内容[请看2#楼]

可以用来做透明处理,类似PNG那样的效果。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2020-1-7 08:28:57 | 显示全部楼层
可以用来做透明处理,类似PNG那样的效果。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
 楼主| 发表于 2020-1-8 07:54:18 | 显示全部楼层
本帖最后由 taomao 于 2020-1-8 13:55 编辑

不是跟aclor这个参数混合改变原图片的颜色吗, tmp_color=piclib_alpha_blend(tmp_color,acolor,mode&0X1F);
回复

使用道具 举报

40

主题

137

帖子

0

精华

高级会员

Rank: 4

积分
579
金钱
579
注册时间
2019-8-4
在线时间
187 小时
 楼主| 发表于 2020-1-8 08:29:18 | 显示全部楼层
本帖最后由 taomao 于 2020-1-8 13:55 编辑

没人吗,自顶一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-11 13:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表