Alpha叠加

news/2024/7/21 6:51:34 标签: CEF, Chromium, Skia, 图像处理

学习过程中的记录,供参考。

foruok原创,转载请保留出处。欢迎关注微信订阅号“程序视界”。

Alpha值的含义

对于 RGBA(或 BGRA )数据, Alpha 通道中存储的 Alpha 值,实际上应该是 Opaque 值,即不透明度。当 Alpha 值为 255 时,表示不透明; Alpha 值为 0 时,表示全透明。

Alpha 值也经常用 0 ~ 1 这个区间的数字来表示。 0 表示全透明, 1 表示不透明。详见这里:https://en.wikipedia.org/wiki/Alpha_compositing。

直接 Alpha 和预乘 Alpha 的区别

Alpha 模式有两种,直接 Alpha 和预乘 Alpha 。

使用直接 Alpha 描述 RGBA 颜色时,颜色的 Alpha 值会存储在 Alpha 通道中。例如,若要描述具有 60% 不透明度的绿色,请使用以下值:(0 , 255 , 0 , 255 * 0.6) = (0 , 255 , 0 , 153)。值 255 指示全绿, 153(255 的 60%)指示颜色应具有 60% 的不透明度。

使用预乘 Alpha 描述 RGBA 颜色时,每种颜色都会与 Alpha 值相乘:(0 * 0.6, 255 * 0.6 , 0 * 0.6 , 255 * 0.6) = (0 , 153 , 0 , 153)。同时 Alpha 值也会存储在 Alpha 通道中。

RGBA图像数据叠加

我只考虑一幅带 Alpha 效果的图像叠加在背景上的情况。

假设背景图像是 B ,无透明效果,带透明效果的图像是 A ,那么透过 A 去看 B ,看上去的图象 C 就是 A 和 B 的混合图象。

假设 A 图像的透明度为 alpha ,则图像 C 的混合公式如下:

R(C) = alpha * R(A) + (1 - alpha) * R(B)
G(C) = alpha * G(A) + (1 - alpha) * G(B)
B(C) = alpha * B(A) + (1 - alpha) * B(B)
A(C) = 1

混合后的图像 C 的Alpha值为 1 ,所以后面的代码里,直接将结果的 Alpha 值设置为 0xFF 。

基于于 Skia 和 PPAPI 的图像叠加代码

我的一个 PPAPI+Skia 示例,使用 Skia 的 SkBitmap 作为后端来绘图,然后再把 SkBitmap 的数据叠加到 PPAPI 的图像数据上。下面是部分代码:

static void blendFromBgraToRgba(void *srcData, void *destData, struct PP_ImageDataDesc &desc)
{
    unsigned char *src = (unsigned char*)srcData;
    unsigned char *dst = (unsigned char*)destData;
    int len = desc.size.height * desc.stride;
    for (int i = 0; i < len; i += 4, src += 4, dst += 4)
    {
        switch(src[3])
        {
        case 0:
            //do nothing
            break;
        case 255:
            dst[0] = src[2]; //Red
            dst[1] = src[1]; //Green
            dst[2] = src[0]; //Blue
            break;
        default:
            dst[0] = (((int)dst[0]) * (255 - src[3])) / 255 + src[2]; //Red
            dst[1] = (((int)dst[1]) * (255 - src[3])) / 255 + src[1]; //Green
            dst[2] = (((int)dst[2]) * (255 - src[3])) / 255 + src[0]; //Blue
            break;
        }
        dst[3] = 0xFF;
    }
}

void XXX::init()
{
    ...
    PPB_ImageData * d;
    d->Describe(m_image, &m_image_desc);
    m_pixels = d->Map(m_image);
    ...
    SkImageInfo ii = SkImageInfo::Make(m_image_desc.size.width, 
            m_image_desc.size.height,
            kBGRA_8888_SkColorType,
            kPremul_SkAlphaType,
            kLinear_SkColorProfileType);
    m_bitmap = new SkBitmap();
    m_bitmap->allocPixels(ii, m_image_desc.stride);
    ...
}

void XXX::paint()
{
    ....
    void *skiaPixels = m_bitmap->getPixels();
    blendFromBgraToRgba(skiaPixels, m_pixels, m_image_desc);
    ...
}

代码有很多可以优化的地方。

参考链接

  • Alpha compositing

就这样吧。

其他参考文章详见我的专栏:【CEF与PPAPI开发】。


http://www.niftyadmin.cn/n/817967.html

相关文章

CEF中访问修改HTML DOM元素

有时你可能想在C代码中直接操作HTML中的某个元素&#xff0c;比如改变某个按钮的状态&#xff08;文字、颜色&#xff09;等&#xff0c;此时可以使用CEF提供的CefDomVisitor、CefDOMDocument、CefDomNode这三个类&#xff0c;包含cef_dom.h即可。 我们可以用它们完成下列任务…

Django项目:CRM(客户关系管理系统)--65--55PerfectCRM实现CRM客户报名状态颜色变化...

1 # kingadmin.py2 # ————————04PerfectCRM实现King_admin注册功能————————3 from crm import models4 #print("kingadmin crm",models.Customer)5 6 # ————————05PerfectCRM实现King_admin注册功能获取内存————————7 # from king_a…

C++多重继承与void*指针转换问题

C支持多重继承&#xff0c;然而多重继承可能会导致一些奇怪的问题&#xff0c;我前段时间遇到一个指针转换问题&#xff0c;非常典型。 先看一个简单的测试代码&#xff1a; #include <iostream> using namespace std;class IA { public:virtual ~IA(){}virtual void …

提高MySql性能的7个技巧

随着尺寸和负载的增长&#xff0c;MySQL的性能会趋于下降。记住这些诀窍&#xff0c;便可保持MySQL的流畅运行。 测量应用程序的方法之一是看性能。而性能的指标之一便是用户体验&#xff0c;通俗的说法就是“用户是否需要等待更长的时间才能得到他们想要的东西”。 这个指标在…

女程序员职业发展的特别之处

在“做自己想做的工作”公开课的互动环节&#xff0c;有位女生提了个问题&#xff0c;大意是“女生是否适合做程序员”&#xff0c;当时我怎么回答的&#xff0c;已经忘差不多了&#xff0c;大意是性别对是否适合做程序员没有直接影响。课后我又仔细琢磨这个问题&#xff0c;联…

【刷题】洛谷 P2675 《瞿葩的数字游戏》T3-三角圣地

题目背景 国王1带大家到了数字王国的中心&#xff1a;三角圣地。 题目描述 不是说三角形是最稳定的图形嘛&#xff0c;数字王国的中心便是由一个倒三角构成。这个倒三角的顶端有一排数字&#xff0c;分别是1 ~ N。1 ~ N可以交换位置。之后的每一行的数字都是上一行相邻两个数字…

通过location响应头实现重定向

package day08;import java.io.IOException;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /*** 案例【location302】 请求重定向* author …

PPAPI插件的全屏切换处理

有时你会想让PPAPI插件全屏&#xff08;比如播放视频时&#xff09;&#xff0c;这次来看看怎么做。 PPAPI和CEF App两侧都要处理。 foruok原创&#xff0c;转载请注明出处。欢迎关注foruok的订阅号“程序视界”(programmer_sight)。 PPAPI插件中的处理 要支持全屏切换&#…