ps如何去水印不留痕迹_水印原理

ps如何去水印不留痕迹_水印原理概述图像叠加与音频叠加(混音)不同,人耳可以同时听到两种声音,因此混音时需要将两种信号都保留;但视频不同,图像一旦叠加,那么叠加区域人眼就只能看到最上层的图像。本文仅阐述对原始图像数据做修改的叠加方式,不涉及多个plane实现显示级别的图像叠加的知识。因此本文所述的图像叠加基本原理就是:顶层图像的像素直接替换掉底层图像的像素,从而新的图像会显示出叠加效果。NV12格式阐述代码/**a…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

概述

图像叠加与音频叠加(混音)不同,人耳可以同时听到两种声音,因此混音时需要将两种信号都保留;但视频不同,图像一旦叠加,那么叠加区域人眼就只能看到最上层的图像。本文仅阐述对原始图像数据做修改的叠加方式,不涉及多个plane实现显示级别的图像叠加的知识。因此本文所述的图像叠加基本原理就是:顶层图像的像素直接替换掉底层图像的像素,从而新的图像会显示出叠加效果。

本文针对NV12像素格式图像的叠加(两张图片均为NV12格式),如果想扩展叠加其他图片,则需先将其他图片转为NV12,然后再进行叠加。如下提供bmp格式的顶图转换路径:

顶图(bmp) —> RGB24 —> NV12 —> 执行叠加操作

NV12格式阐述

nv12像素的存储格式可参考:https://blog.csdn.net/lyy901135/article/details/97934892
如下红框地方则为需要替换的区域,只要将如下两个红框内的值替换为对应“顶图”的值就完成了图像的叠加。那么首先就要确认两个红框内的每个像素的位置和红框的大小。

  • Y数据内的红框
    顶图的宽高为144×48,根据NV12的像素组织特点可知,(x,y)对应的红框大小也为144×48,此处的(x,y)对应代码中的(pos_x, pos_y)。代码中rect_y表示Y数据中矩形框起始地址,
    rect_y = 底图基址(对应坐标原点) + w*y + x,对应代码rect_y = param->bm_buff + param->pos_y * param->bm_w + param->pos_x;
    矩形框内每个像素点的位置关系:

    /* i 遍历行,j遍历列, w=1920, h=1080*/
    for (i=0; i < 48; i++) { 
         
    	/* i 行对应的基址 */
    	rect_tmp_y = rect_y + i*w;
    	for (j=0; j < 144; j++) { 
         
    		Y(x+j, y+i) = rect_tmp_y + j;
    	}
    }
    
  • UV数据内的红框
    顶图的宽高为144×48,根据NV12的像素组织特点可知,(x’,y’)对应的红框大小则为144×24(每两行Y对应一行UV,所以高度减半:48 -> 24)。代码中rect_u表示UV数据中矩形框起始地址,
    rect_u = 底图基址(对应坐标原点)+ wh + yw/2 + x,对应代码rect_u = param->bm_buff + param->bm_w * param->bm_h + param->pos_y * param->bm_w / 2 + param->pos_x; 正是由于每两行Y才对应一行UV数据的特性,因此再计算偏移时累加的是w的一半,对应上述公式中+ y*w/2
    矩形框内每个像素点的位置关系:

    /* i 遍历行,j遍历列, w=1920, h=1080*/
    for (i=0; i < 48; i++) { 
         
    	/* i 行对应的uv基址,每两行才更新一次uv基址 */
    	if (i % 2 == 0) { 
         
    		rect_tmp_u = rect_u + i * param->bm_w / 2;
    		rect_tmp_v = rect_tmp_u + 1;
    	}
    	/* 每两行Y对应一行UV,Y的偶数行对应UV行的U数据,并且U还要求在偶数列位置才取值; * Y的奇数行对应UV行的V数据,并且V还要求在奇数列才取值。 */
    	for (j=0; j < 144; j++) { 
         
    		if ((i % 2 == 0) && (j % 2 == 0)) { 
         
    			/* U(x+j, y+i)的位置, 偶数行,偶数列 */
    			rect_tmp_u += 2;
    		} else if ((i % 2 == 1) && (j % 2 == 1)) { 
         
    			/* V(x+j, y+i)的位置, 奇数行,奇数列 */
    			rect_tmp_v += 2;
    		}
    	}
    }
    

在这里插入图片描述

代码

/* * author: francis.fan@rock-chip.com * date: 2019-8-2 */

typedef struct _overlayParam { 
   
	unsigned char *bm_buff; //base map buff
	int bm_w; //base map width
	int bm_h; //base map height

	unsigned char *top_buff; //top overlay buff
	int top_w;
	int top_h;

	int pos_x; //position x [0, bm_w-top_w]
	int pos_y;
}overlayParam;

void dump_overlayparam(overlayParam *param)
{ 
   
	printf("=== overlayParam ===\n");
	printf("\tbm_buff:%p\n", param->bm_buff);
	printf("\tbm_w:%d\n", param->bm_w);
	printf("\tbm_h:%d\n\n", param->bm_h);
	printf("\ttop_buff:%p\n", param->top_buff);
	printf("\ttop_w:%d\n", param->top_w);
	printf("\ttop_h:%d\n\n", param->top_h);
	printf("\tpos_x:%d\n", param->pos_x);
	printf("\tpos_y:%d\n", param->pos_y);
}

/* 功能:nv12图像叠加 */
int pixel_format_nv12_overlay(overlayParam *param)
{ 
   
	unsigned char *rect_y = NULL;
	unsigned char *rect_u = NULL;
	unsigned char *rect_v = NULL;
	unsigned char *rect_tmp_y = NULL;
	unsigned char *rect_tmp_u = NULL;
	unsigned char *rect_tmp_v = NULL;
	unsigned char *top_y = NULL;
	unsigned char *top_u = NULL;
	unsigned char *top_v = NULL;
	int i, j;

	dump_overlayparam(param);

	if (!param || !(param->bm_buff) || !(param->top_buff) ||
		((param->bm_w * param->bm_h) <= 0) || ((param->top_w * param->top_h) <= 0) ||
		(param->pos_x < 0) || (param->pos_y < 0)) { 
   
		printf("ERROR: %s input args invalid!\n", __func__);
		return -EINVAL;
	}

	/* Position align */
	param->pos_x = (param->pos_x / 2) * 2;
	param->pos_y = (param->pos_y / 2) * 2;

	if (((param->pos_x + param->top_w) >= param->bm_w) ||
		(((param->pos_y + param->top_h) >= param->bm_h))) { 
   
		printf("ERROR: %s overlay img size invalid!\n", __func__);
		return -EINVAL;
	}

	/* * 以(pos_x, pos_y)为起始点分别向右(x轴)和向下(y轴)画一个矩形框(图片左上角为原点), * 矩形框的款高就是顶图的宽高。该矩形框便是需要替换成顶图的区域。 */
	rect_y = param->bm_buff + param->pos_y * param->bm_w + param->pos_x;
	rect_u = param->bm_buff + param->bm_w * param->bm_h + param->pos_y * param->bm_w / 2 + param->pos_x;
	rect_v = rect_u + 1;
	top_y = param->top_buff;
	top_u = param->top_buff + param->top_w * param->top_h;
	top_v = top_u + 1;

	for (i = 0; i < param->top_h; i++) { 
   
		rect_tmp_y = rect_y + i * param->bm_w;
		if (i % 2 == 0) { 
   
			rect_tmp_u = rect_u + i * param->bm_w / 2;
			rect_tmp_v = rect_tmp_u + 1;
		}

		for (j = 0; j < param->top_w; j++) { 
   
			/* Replace y value */
			*(rect_tmp_y + j) = *(top_y + i * param->top_w + j);

			if ((i % 2 == 0) && (j % 2 == 0)) { 
   
				*rect_tmp_u = *top_u;
				top_u += 2;
				rect_tmp_u += 2;
			} else if ((i % 2 == 1) && (j % 2 == 1)) { 
   
				*rect_tmp_v = *top_v;
				top_v += 2;
				rect_tmp_v += 2;
			}
		}
	}

	return 0;
}

工程

工程地址(包含Makefile和测试使用的NV12图片):
https://download.csdn.net/download/lyy901135/11467723

运行命令:./nv12_add_nv12 images/base_map.nv12 images/top.nv12 images/output.nv12
在这里插入图片描述
查看顶图命令:ffplay -s 144x48 -f rawvideo -pixel_format nv12 images/top.nv12
在这里插入图片描述
查看叠加后底图命令:ffplay -s 1920x1080 -f rawvideo -pixel_format nv12 images/output.nv12
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/189991.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 单点登录sso的实现原理(单点登录原理)

    什么是单点登录一个账户在多个系统上实现单一用户的登录为什么用单点登录单点登录可以做到在不记录用户密码的情况下,实现不同系统之间的资源共享,自动登录不安全,单点登录,一处登录,处处都可用,不用做多余的登录操作引用一个很经典的案例比如现在有OA系统、门户系统、人力资源管理系统、档案管理系统、生产管理系统、xx系统等,这么多个系统在一个公司里面,如果一个用户需要使用这么多个系统,那每天都要登录…

    2022年4月14日
    42
  • 已刻游戏目录

    已刻游戏目录单机游戏1.生化奇兵1、2、32.蔷薇少女格斗3.全女格斗2.04.劲乐团5.魔兽争霸6.生化危机1-6启示录7.MaxPayne2+38.寄生前夜9.恐龙危机1、210.梦幻模拟战4、511.PS模拟器:北欧女神、放浪冒险谭、寄生前夜、寂静岭1、异度装甲、月下夜想曲、古惑狼1-3、封神演义、苍魔灯、鬼屋魔影、武藏传12.FC模拟器13.MD模拟器14.杀手4…

    2022年5月8日
    33
  • JavaScript设计模式—-策略模式[通俗易懂]

    JavaScript设计模式—-策略模式[通俗易懂]声明:这个系列为阅读《JavaScript设计模式与开发实践》—-曾探@著一书的读书笔记1.策略模式的定义将不变的部分和变化的部分隔开是每个设计模式的主题。定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。2.策略模式的目的将算法的使用与算法的实现分离开来。3.传统语言中的策略模式和JavaScript中的策略模式对比3.1.传统语言中的策略模式使用策略模式来实现计算奖金v

    2022年7月12日
    15
  • 自己用命令强制删除占用的文件或文件夹

    自己用命令强制删除占用的文件或文件夹&#13; 前言&#13;有没有遇到过一些情况?软件卸载了,有些文件夹就是删不掉,提示被占用,mmp,这时候你肯定想到了360文件粉碎机!&#13;mmp,我就删个文件夹还要装个360?谁不知道360是个“大毒瘤”!&#13;自己动手丰衣足食!&#13; 正文&#13;这时候就想到了强大的shell命令,百度一波,还真找到了,&#13;DEL和RD这两个命令可以完…

    2022年5月10日
    45
  • Pytest(5)美化插件进度条pytest-sugar

    Pytest(5)美化插件进度条pytest-sugar前言在我们进行自动化测试的时候,用例往往是成百上千,执行的时间是几十分钟或者是小时级别。有时,我们在调试那么多用例的时候,不知道执行到什么程度了,而pytest-sugar插件能很好解决我们的痛点。

    2022年7月30日
    36
  • 【ztree系列】树节点的模糊查询

    【ztree系列】树节点的模糊查询以前设计模糊查询的功能,一般都是针对表格来做的,还真没考虑过对tree进行模糊查询,也可能是因为遇到的数据量还没到头疼的程度吧。为了完美的实现模糊查询的效果,搞了半天css,对输入框显示效果的设置更是修改了n多次,什么半圆角、边框、光影。。。真佩服我这颗屡试屡换的小心脏啊一、页面设计对于搜索功能,首先要有输入框,用于接收输入内容;然后就是显示搜索结果用的标签,控制焦点用的上移下动按钮。其实

    2022年5月29日
    297

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号