仿造微信截图工具

起因:身处大学身不由己,总有些社团活动需要拉外联啥的,一拉外联就的朋友圈发广告,还不能发私密。为了一劳永逸的解决这个问题,自己用pyhton写了一个类似于p图的代码。

目的:将一张朋友圈截图中的某一矩形区域替换为另一图片中的矩形区域。

原理:利用opencv给图片加上滑动条以及实现截取区域。

使用方法:在source窗口截取矩形区域,在material窗口点击会自动勾出等大矩形区域,按空格保存图片。

不足:滑动条部分,两张图片是共享的,现在懒得改了。。。。

代码:

#include<opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int h_x = 0, v_y = 0, d_x = 0, d_y = 0;  //记录滑动条变化值,以及保存当前值
Rect v_bar, h_bar;
bool x_change = false;
bool y_change = false; //判断是否改变
bool drawbox = false;
int width, height;
Rect source_rect, _rectangle, product_rect;
int img_x=0, img_y=0;   //记录滑动后截取图片在原图片中的位置
Rect roi_sour, roi_mater;    //进行p图的部分

void on_mouse(int event, int x, int y, int flags, void* param);
void draw_scrolls(Mat src_img,Mat& tempimg, const char* title, int width = 1400, int height = 700);
void DrawRect(Mat& img, Rect box);
void on_mouse_2(int event, int x, int y, int flags, void* param);
void ROI_linearBlending(Mat srcImg_1, Mat srcImg_2);

int main()
{
	const char* title = "source";
	const char* title2 = "material";
	Mat srcimg = imread("E:\\material\\pyq1.png");
	Mat srcimg2 = imread("E:\\material\\pyq2.png");
	Mat dstimg1,dstimg2;
	Mat tempimg1,tempimg2;
	namedWindow(title, 1);
	namedWindow(title2, 1);
	setMouseCallback(title, on_mouse);
	setMouseCallback(title2, on_mouse_2);
	while (true)
	{
		char c = waitKey(10);
		draw_scrolls(srcimg, dstimg1,title);
		draw_scrolls(srcimg2, dstimg2, title2);
		dstimg1.copyTo(tempimg1);
		dstimg2.copyTo(tempimg2);
		if (drawbox)
		{
			DrawRect(tempimg1, _rectangle);//绘制标识符为真时,画矩形
			roi_sour=(Rect(_rectangle.x + img_x, _rectangle.y + img_y, _rectangle.width, _rectangle.height));
		}
		DrawRect(tempimg2, product_rect);
		roi_mater = (Rect(product_rect.x+img_x, product_rect.y+img_y, product_rect.width, product_rect.height));
		if (c == ' ')
			break;
		imshow(title, tempimg1);
		imshow(title2, tempimg2);
	}
	ROI_linearBlending(srcimg, srcimg2);
	waitKey(0);

}

//图片加滑动条
void draw_scrolls(Mat src_img, Mat& temp_img,const char* title, int width, int height)
{
	Mat src_rect, temp_rect;
	Mat src_roi;
	Rect v_rect, h_rect;
	int img_width, img_height;  //img的width和height
	int win_width, win_height;  //window的width和height
	int show_width, show_height;  //窗口中图片的width和height
	int bar_width = 25;  //滑动条的宽度
	double scale_h, scale_w;  //img和window的width,height之比





	img_width = src_img.cols;
	img_height = src_img.rows;
	win_width = show_width = min(img_width, width);
	win_height = show_height = min(img_height, height);
	scale_h = (double)img_height / height;
	scale_w = (double)img_width / width;

	//高度过高需要加竖直滑动
	if (scale_h > 1)
	{
		win_width = img_width > width ? width + bar_width : img_width + bar_width;
		show_width = win_width - bar_width;
	}
	//宽度过宽需要加水平滑动
	if (scale_w > 1)
	{
		win_height = img_height > height ? height + bar_width : img_height + bar_width;
		show_height = win_height - bar_width;
	}

	temp_img = Mat::zeros(Size(win_width, win_height), CV_8UC3);

	if (scale_h > 1)
	{
		v_y += d_y;
		d_y = 0;
		v_y = v_y < 0 ? 0 : (v_y > (int)((1 - 1 / scale_h) * win_height) ? (int)((1 - 1 / scale_h) * win_height) : v_y);
		img_y = (int)(v_y * img_height / win_height);//img_y = (int)(v_y / ((1-1/scale_h) * win_height) * (1 - 1 / scale_h)*img_height)的简化

		v_rect = Rect(show_width + 1, 0, bar_width, win_height);  //竖直滑动条底层
		v_bar = Rect(show_width + 1, v_y, bar_width, (int)((double)win_height / scale_h));  //竖直滑动条
		rectangle(temp_img, v_rect, Scalar::all(0), -1);
		rectangle(temp_img, v_bar, Scalar::all(255), -1);
	}
	if (scale_w > 1)
	{
		h_x += d_x;
		d_x = 0;
		h_x = h_x < 0 ? 0 : (h_x > (int)((1 - 1 / scale_w) * win_width) ? (int)((1 - 1 / scale_w) * win_width) : h_x);
		img_x = (int)(h_x * img_width / win_width);//img_y = (int)(v_y / ((1-1/scale_h) * win_height) * (1 - 1 / scale_h)*img_height)的简化

		h_rect = Rect(0, show_height + 1, win_width, bar_width);  //水平滑动条底层
		h_bar = Rect(img_x, show_height + 1, (int)((double)win_width / scale_w), bar_width);   //水平滑动条
		rectangle(temp_img, h_rect, Scalar::all(0), -1);
		rectangle(temp_img, h_bar, Scalar::all(255), -1);
	}
	temp_rect = temp_img(Rect(0, 0, show_width, show_height));   //窗口显示图片部分
	src_rect = src_img(Rect(img_x, img_y, show_width, show_height));   //原图截取部分
	src_rect.copyTo(temp_rect);

}

//在第一张图上截取的部分
void on_mouse(int event, int x, int y, int flags, void* param)
{
	Point curse = Point(x, y);
	Point end, now;
	static Point start = Point(-1, -1);    //定义静态变量
	//点击滑动条
	if (event == EVENT_LBUTTONDOWN)
	{
		start = Point(x, y);
		if (v_bar.contains(curse))
			y_change = true;
		else if (h_bar.contains(curse))
			x_change = true;
		else
		{
			cout <<start<<"\n";
			drawbox = true;
		}
	}

	//拖动
	if (event == EVENT_MOUSEMOVE)
	{
		if (y_change)                                                        
		{
			now = Point(x, y);
			d_y = now.y - start.y;
			start = now;
		}
		if (x_change)
		{
			now = Point(x, y);
			d_x = now.x - start.x;
			start = now;
		}
		if (drawbox)
		{
			now = Point(x, y);
		}
	}
	if (event == EVENT_LBUTTONUP)
	{
		x_change = y_change = false;
		end = Point(x, y);
		width = end.x - start.x > 0 ? end.x - start.x : start.x - end.x;
		height = end.y - start.y > 0 ? end.y - start.y : start.y - end.y;
		source_rect = Rect(start, end);
		//DrawRect(tempimg1,source_rect);
		drawbox = false;
	}
	_rectangle = Rect(start, now);

}

//第二章图上截取
void on_mouse_2(int event, int x, int y, int flags, void* param)
{

	Point curse = Point(x, y);
	Point end, now;
	static Point start = Point(-1, -1);
	bool l_drawbox = false;
	//点击滑动条
	if (event == EVENT_LBUTTONDOWN)
	{
		start = Point(x, y);
		if (v_bar.contains(curse))
			y_change = true;
		else if (h_bar.contains(curse))
			x_change = true;
		else
		{
			cout << "(" << x << "," << y << ")";
			product_rect = Rect(x, y, width, height);
			l_drawbox = true;
		}
	}

	//拖动
	if (event == EVENT_MOUSEMOVE)
	{
		if (y_change)
		{
			now = Point(x, y);
			d_y = now.y - start.y;
			start = now;
		}
		if (x_change)
		{
			now = Point(x, y);
			d_x = now.x - start.x;
			start = now;
		}
	}
	if (event == EVENT_LBUTTONUP)
	{
		x_change = y_change = false;
		l_drawbox = false;
	}

}

//画矩形
void DrawRect(Mat& img, Rect box)
{
	RNG& rng = theRNG();
	rectangle(img, box.tl(), box.br(), Scalar(rng.uniform(0, 255),
		rng.uniform(0, 255), rng.uniform(0, 255)));  //以(0,255)内均匀随机数作为矩形颜色
}


//p图
void ROI_linearBlending(Mat srcImg_1, Mat srcImg_2)
{
	Mat	imgROI1, imgROI2, temp1, temp2, dst;
	srcImg_1.copyTo(temp1);
	srcImg_2.copyTo(temp2);
	imgROI1 = temp1(roi_sour);
	imgROI2 = temp2(roi_mater);
	addWeighted(imgROI1, 0., imgROI2, 1., 0., imgROI1);
	imshow("dst", temp1);
	imwrite("E:\\material\\result1.png", temp1);
}

素材:
素材1
素材2
结果:
改变了头像

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Web是一种使用Java语言开发的Web应用程序开发技术。仿造当当网是指在Java Web的基础上,通过学习当当网的功能和界面设计,开发一个类似于当当网的电子商务网站。 首先,需要搭建一个Java Web开发环境,可以使用Eclipse、IntelliJ IDEA等集成开发环境,并选择合适的服务器,如Tomcat。 接下来,需要设计数据库结构,包括商品信息、用户信息、订单信息等。可以使用MySQL等关系型数据库进行数据管理。 然后,创建JavaBean类来映射数据库中的表,并实现相应的业务逻辑,如用户登录注册、商品展示、购物车管理、订单处理等功能。可以使用JDBC等方式与数据库进行交互。 同时,需要使用HTML、CSS、JavaScript等前端技术实现网页的外观和交互效果。可以借助Bootstrap等前端框架来提升开发效率。 此外,还需要对网站进行性能优化和安全防护,如使用缓存技术提高访问速度,使用SSL证书保护用户信息等。 最后,进行测试和部署。可以使用JUnit等测试框架对功能进行测试,然后将应用程序部署到服务器上,使其可以通过互联网访问。 通过以上步骤,就可以实现一个简单的仿造当当网的Java Web应用程序。当然,要实现真正的电子商务网站,还需要更多的功能和复杂的设计,如商品搜索、评论系统、物流配送等。因此,需要持续学习和不断改进,从而完善自己的开发技术和项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值