前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >BGRA RGBA YUV420互相转换

BGRA RGBA YUV420互相转换

原创
作者头像
Tomas7571
发布2023-06-29 12:11:57
1.3K0
发布2023-06-29 12:11:57
举报
文章被收录于专栏:Tomas7571的专栏

一、存储格式

1. BGRA32

BGRA在内存上的排列按B、G、R、A依次排列,32表示每个通道占1个字节8bits,一个像素占4个字节32bits

2. RBGA32

RBGA在内存上的排列按R、B、G、A依次排列

3. YUV420(I420)

YUV420在内存上的排列为,先是全部Y,然后是全部U,最后是全部V

二、格式转换

1. BGRA和RBGA互转

只需遍历一遍,把每4个字节的第一位和第三位互换即可

void ConvertBGRAtoRGBA(BYTE* data, int width, int height)

{

for (int i = 0; i < width * height * 4; i += 4) {

BYTE temp = data[i];

data[i] = data[i + 2];

data[i + 2] = temp;

}

}

2. YUV420转RBGA

按照上图YUV420的存储格式,蓝色部分4个Y、1个U、1个V可以转换出4个像素的RBGA格式。

void I420ToRGBA(const uint8_t* src_y, const uint8_t* src_u, const uint8_t* src_v, uint8_t* dst_rgba, int width, int height)

{

// 计算公式

//R = Y + 1.13983 * V

//G = Y - 0.39465 * U - 0.58060 * V

//B = Y + 2.03211 * U

const int src_y_stride = width;

const int src_u_stride = (width + 1) / 2;

const int src_v_stride = (width + 1) / 2;

const int dst_rgba_stride = width * 4;

for (int y = 0; y < height; ++y) {

const uint8_t* src_y_row = src_y + y * src_y_stride;

const uint8_t* src_u_row = src_u + (y / 2) * src_u_stride;

const uint8_t* src_v_row = src_v + (y / 2) * src_v_stride;

uint8_t* dst_rgba_row = dst_rgba + y * dst_rgba_stride;

for (int x = 0; x < width; ++x) {

const int src_y_val = src_y_row[x];

const int src_u_val = src_u_row[x / 2];

const int src_v_val = src_v_row[x / 2];

const int c_val = src_y_val - 16;

const int d_val = src_u_val - 128;

const int e_val = src_v_val - 128;

const int r_val = (298 * c_val + 409 * e_val + 128) >> 8;

const int g_val = (298 * c_val - 100 * d_val - 208 * e_val + 128) >> 8;

const int b_val = (298 * c_val + 516 * d_val + 128) >> 8;

dst_rgba_row[x * 4 + 0] = static_cast<uint8_t>(max(0, min(255, r_val)));

dst_rgba_row[x * 4 + 1] = static_cast<uint8_t>(max(0, min(255, g_val)));

dst_rgba_row[x * 4 + 2] = static_cast<uint8_t>(max(0, min(255, b_val)));

dst_rgba_row[x * 4 + 3] = 255;

}

}

}

三、图片显示

这里用Windows GDI的方式把图片直接绘制在窗口上 CBitmap用的是BGRA格式的数据,显示I420的话,把格式转换一下再组装为CBitmap即可。

void CPicViewerDlg::DrawBitmap(CWnd *pWnd, int x, int y, int w, int h, unsigned char *pData)

{

CBitmap bitmap;

CDC MemDc;

bitmap.CreateBitmap(w, h, 1, 32, pData);

CDC *pWndDc = pWnd->GetDC();

MemDc.CreateCompatibleDC(pWndDc);

CBitmap *pOldBitmap = MemDc.SelectObject(&bitmap);

pWndDc->BitBlt(x, y, w, h, &MemDc, 0, 0, SRCCOPY);

MemDc.SelectObject(pOldBitmap);

pWnd->ReleaseDC(pWndDc);

pWndDc = NULL;

}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、存储格式
    • 1. BGRA32
      • 2. RBGA32
        • 3. YUV420(I420)
        • 二、格式转换
          • 1. BGRA和RBGA互转
            • 2. YUV420转RBGA
            • 三、图片显示
            相关产品与服务
            图片处理
            图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档