1,水印或者弹幕实现的效果图
2,因为Camera Hal3中图像的格式yuv420sp格式,那么水印或者弹幕就需要转换成yuv420sp的格式,这样才能将水印或者弹幕的图像合成到camera的每一帧图像中。水印或者弹幕的图像这里提供的是32×24 bmp格式的图像,如图:
这个提供水印图像主要是数组和字母,空格,冒号,斜线和部分汉字。
水印或者弹幕图像的下载路径:https://download.csdn.net/download/jiangchaobing_2017/88540699
3,下面就是通过fopen和fread函数去打开读取水印bmp格式的图像
int WaterMark::InitwWaterMark()
{
FILE *fp = NULL;
int i;
int pic_width = 0, pic_height = 0;
char filename[256];
unsigned char *argb_buf = NULL;
for(i = 0; i < MAX_ICON_NUM; i++) {
sprintf(filename, "%s/argb8888_24x32_%d.bmp", WATERMARK_BMP_DIR, i);
ALOGE("open file %s\n", filename);
fp = fopen(filename, "r");
if(NULL == fp) {
ALOGE("Fail to open file %s(%s)!", filename, strerror(errno));
goto OPEN_FILE_ERR;
}
icon_arry[i].id = i;
fseek(fp, 18, SEEK_SET);
fread(&pic_width, 1, 4, fp);
fread(&pic_height, 1, 4, fp);
icon_arry[i].width = abs(pic_width);
icon_arry[i].height = abs(pic_height);
ALOGE("real width=%d(%d), height=%d(%d)\n", icon_arry[i].width, pic_width, icon_arry[i].height, pic_height);
icon_arry[i].y = (unsigned char*)malloc(icon_arry[i].width * icon_arry[i].height*5/2);
if(NULL == icon_arry[i].y) {
ALOGE("malloc picture yuv fail !\n");
fclose(fp);
goto ALLOC_Y_ERR;
}
memset(icon_arry[i].y, 0xff, (icon_arry[i].width * icon_arry[i].height*5/2));
icon_arry[i].alph = icon_arry[i].y + icon_arry[i].width * icon_arry[i].height;
icon_arry[i].c = icon_arry[i].alph + icon_arry[i].width * icon_arry[i].height;
argb_buf = (unsigned char *)malloc(icon_arry[i].width * icon_arry[i].height * 4);
if (NULL == argb_buf) {
ALOGE("malloc bmp buf fail !\n");
fclose(fp);
goto ALLOC_BUF_ERR;
}
fseek(fp, 54, SEEK_SET);
fread(argb_buf, icon_arry[i].width * icon_arry[i].height * 4, 1, fp);
ARGB8888ToYUV420sp(argb_buf, icon_arry[i].width, icon_arry[i].height,
icon_arry[i].y, icon_arry[i].c, icon_arry[i].alph);
fclose(fp);
free(argb_buf);
}
return 0;
ALLOC_BUF_ERR:
ALLOC_Y_ERR:
OPEN_FILE_ERR:
for(i = 0; i < MAX_ICON_NUM; ++i) {
if(icon_arry[i].y != NULL) {
free(icon_arry[i].y);
icon_arry[i].y = NULL;
}
}
return -1;
}
而这里ARGB8888ToYUV420sp主要是将bmp格式解析处理的图像数据转换成yuv420sp格式。rgb转yuv的换算公式:
4,将水印转换的yuv格式图像和camera的图像进行合成成一帧图像
void WaterMark::Yuv420spBlending(unsigned char *bg_y, unsigned char *bg_c, int bg_width, int bg_height,
int left, unsigned int top, int fg_width, int fg_height,
unsigned char *fg_y, unsigned char *fg_c, unsigned char *alph)
{
unsigned char *bg_y_p = NULL;
unsigned char *bg_c_p = NULL;
int i = 0;
int j = 0;
bg_y_p = bg_y + top * bg_width + left;
bg_c_p = bg_c + (top >>1)*bg_width + left;
for(i = 0; i<(int)fg_height; i++) {
if((i&1) == 0) {
for(j=0; j< (int)fg_width; j++) {
*bg_y_p = ((256 - *alph)*(*bg_y_p) + (*fg_y++)*(*alph))>>8;
*bg_c_p = ((256 - *alph)*(*bg_c_p) + (*fg_c++)*(*alph))>>8;
alph++;
bg_y_p++;
bg_c_p++;
}
bg_c_p = bg_c_p + bg_width - fg_width;
} else {
for(j=0; j< (int)fg_width; j++) {
*bg_y_p = ((256 - *alph)*(*bg_y_p) + (*fg_y++)*(*alph))>>8;
alph++;
bg_y_p++;
}
}
bg_y_p = bg_y_p + bg_width - fg_width;
}
}
因为是yuv420sp的格式,uv格式高度只有y的1/2,需要稍微特殊处理。另外就是alpha实现背景透明程度。
5,完整的水印或者弹幕算法代码下载路径:
https://download.csdn.net/download/jiangchaobing_2017/88540687
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/181998.html