首页 > 其他分享 >简述:将带透明通道的PNG图片叠加到Framebuf上

简述:将带透明通道的PNG图片叠加到Framebuf上

时间:2024-04-21 19:35:11浏览次数:22  
标签:叠加 Framebuf 简述 f32 let background alpha PNG

PNG图片,维基百科简介:https://zh.wikipedia.org/wiki/PNG
现在带透明通道的最常见的PNG文件都是PNG 32格式,所以首先将PNG文件解析为RGBA-8-8-8-8即32位真彩像素(PNG 32)(A代表Alpha透明通道)

PNG 帧解析

PNG文件编码比BMP复杂一点,但还是可以解析的。在no_std rust上我就偷懒使用了minipng库。
如果你需要c语言,可以自己写一个,参考标准文档RFC2083即可

文件帧主要是单层TLV(Type-Length-Value)的方式。

RFC 2083 总结来说就是:

Header:文件格式头/也叫文件署名域,用于标识是否为PNG文件,避免了与其他格式的冲突和误判。
一个文件里有格式头,还有多个数据块。
每个数据块都由几个元素构成:长度,类型,数据体,CRC。这个基本所有的协议和文件都有类似设计。

PNG 定义了两种类型的数据块(chunk),一种是标准的关键数据块(critical chunk),另一种可选的辅助数据块(ancillary chunks)。我们只需要标准的关键数据块。

这里找到一篇表格化的帧解析文章:https://blog.csdn.net/qq_60131542/article/details/123450382

压缩算法:LZ77,哈夫曼huffman,Quantization

以下数据块I字开头是Image的意思

  • IHDR,这个是图片头块,包括了图片信息:宽高、位深、颜色类型、压缩算法、滤波器方法、隔行扫描方法。
  • PLTE 调色板区块(可选)
  • IDAT 图片数据块,像素RGBA就在这里。该区有多个块
  • IEND 图片结束块,也是特定的几个字节。
    还有其他的辅助区,但是一般我们用不到。总之TLV的方式可以让你通过 Type区分+Len偏移 只去拿需要的数据,而不用管其他区。

总之,RGBA从PNG文件解出来即可。

叠加算法

需要注意的是,透明通道A在屏幕上是不存在的,它唯一的作用是用于和背景运算叠加。也就是说,A通道是需要有背景色才能运算的。

这是将屏幕的RGB像素与现在PNG的RGBA像素合并/叠加的算法:
屏幕只能显示RGB,所有的A通道都会通过计算后叠加到RGB各分量上面

    fn blend_rgba_to_rgb(&self, background: &mut BltPixel) {
        // Alpha Blending
        // Result = Foreground×α + Background×(1−α)
        let alpha = self.0[3] as f32 / 255.0;
        let r = self.0[0] as f32;
        let g = self.0[1] as f32;
        let b = self.0[2] as f32;

        let blended_r = ((1.0 - alpha) * background.red as f32 + alpha * r) as u8;
        let blended_g = ((1.0 - alpha) * background.green as f32 + alpha * g) as u8;
        let blended_b = ((1.0 - alpha) * background.blue as f32 + alpha * b) as u8;

        background.red = blended_r;
        background.green = blended_g;
        background.blue = blended_b;
    }

以下是矩形叠加

///数学公式解法
//设:需要将png渲染到屏幕framebuf上矩形mfb上
//设:png的图片大小为(size_xp,size_yp)
//当前正在叠加渲染的坐标为 (x,y)
                for y in 0..size_yp {
                    for x in 0..size_xp {
                        vec_png[x + y * size_xp].blend_blt_pixel(&mut mfb[x + y * size_xp]);
                    }
                }

我们把从PNG文件里解出来的RGBA像素通过矩形叠加到屏幕framebuf的像素上,即可完成PNG的显示。
如果没办法获得矩形部分的mfb(mframebuf),也可以直接获取全屏framebuf再通过计算 需要渲染的起点坐标偏移(x0,y0),完成矩形部分叠加。

标签:叠加,Framebuf,简述,f32,let,background,alpha,PNG
From: https://www.cnblogs.com/yucloud/p/18149373/png_rgba_2_rgb_framebuf

相关文章

  • 简述Linux磁盘IO
    1、什么是磁盘在讲解磁盘IO前,先简单说下什么是磁盘。磁盘是可以持久化存储的设备,根据存储介质的不同,常见磁盘可以分为两类:机械磁盘和固态磁盘。1.1 机械磁盘第一类,机械磁盘,也称为硬盘驱动器(HardDiskDriver),通常缩写为HDD。机械磁盘主要由盘片和读写磁头组成,数据就存......
  • BGP基础(简述)欢迎有问题补充
    动态路由协议IGP:内部网关路由协议,运行在AS内的路由协议RIP:四层、应用层、UDP封装、端口号520、距离矢量路由协议、度量值为跳数OSPF:三层、网络层、IP封装、端口号89、链路状态路由协议、度量值为宽带ISIS:二层、数据链路层、IEEE802.3封装、链路状态路由协议EGP:外部网关路由......
  • 简述多线程中的锁与sleep
    面试中经常被问到,在多线程/加锁环境下使用sleep可能出现的问题,首先总结一下这些问题基本都出自sleep不会释放锁这一点(与wait()截然相反)。1sleep可能会引发的问题线程持有锁时休眠:当一个线程在持有锁的情况下调用sleep()时,它会在睡眠时仍保持锁的状态,此时其他线程将无法访......
  • C#事件简述
    C#事件简述有人说事件就是特殊的多播委托,有人说不是,仁者见仁智者见智,用起来是差不多的。1、首先声明一个委托publicdelegatevoid一个示例委托();这个委托一般就是一个归类作用,基于这个委托我可以创建很多个同类型(返回值相同、参数值类型相同,业务逻辑类似)的事件,例如:......
  • 开源许可协议简述
     一、开源许可协议简述开源许可协议是指开源社区为了维护作者和贡献者的合法权利,保证软件不被一些商业机构或个人窃取,影响软件的发展而开发的协议。它的中文名:开源许可协议;外文名:opensourcelicense。二、开源许可协议之间的区别与联系通过上图,可以很清晰的了解到6......
  • 实验人员A在操作过程中不慎将装有4L乙腈的瓶子打碎,请简述此时应采取的应急处理措施
    实验人员A在操作过程中不慎将装有4L乙腈的瓶子打碎,应立即按照实验室化学品泄漏应急处理方案以及乙腈特定的应急处置指南来行动。以下是针对这一紧急情况应采取的应急处理措施:人身安全优先:撤离现场:实验人员A应立即停止所有操作,避免直接接触泄漏物,并迅速离开泄漏区域。同时,通知......
  • OSPF中配置静态路由负载分担实验简述
    OSPF中配置静态路由负载分担实验简述在静态路由负载分担中,多个路由器被配置为共享负载的目标,以实现流量的均衡分配。到达目的地有N条相同度量值的路径,默认值60,N条路由是等价路由,数据报文在N条链路上轮流发送。静态路由负载分担的优点是简单易用,不需要额外的负载均衡设备......
  • [工具] png图片打包plist工具,手把手教你使用pngPackerGUI_V2.0
    png图片打包plist工具,手把手教你使用pngPackerGUI_V2.0此软件是在pngpacker_V1.1软件基础之后,开发的界面化操作软件,方便不太懂命令行的小白快捷上手使用。1.下载并解压缩软件,得到如下目录,双击打开pngPackerGUI.exe 2.打开pngPackerGUI之后,默认的界面如下: 3.选择目录:选......
  • [工具] 批量BMP图片转为PNG透明图片,去掉BMP黑色背景,去黑底,压缩导出png图片V1.1
    批量BMP图片转为PNG透明图片,去掉BMP黑色背景,压缩导出png图片V1.1前段时间上传了一款bmp转png并去黑底的demo软件,非常受欢迎,  上一版本地址:批量BMP图片转为PNG透明图片,去掉BMP黑色背景应广大爱好者的要求,完善了一下软件的功能,增加了导出png图片压缩功能,界面如下:  压......
  • Java面试题:Java集合框架:请简述Java集合框架的主要组成部分,并解释它们之间的关系。
    Java集合框架(JavaCollectionsFramework)是一组用来表示和操作集合的类的集合,它提供了用于存储不同类型对象的标准化接口和类。Java集合框架的主要组成部分包括以下几个部分:集合接口(CollectionInterface):这是所有集合类的根接口,定义了集合的基本操作,如添加、删除、判断存在......