使用GDI+对位图进行“显示”,"扩展",“拼接”,“切割”操作

最近项目中用到了GDI+对位图进行了这些操作,现在记录下来,也希望可以帮助到一些需要它的同学

在VS2017环境,MFC对话框程序

显示

对位图的显示 也就是加载,代码方法如下

//1.使用picture控件 将type设置为Bitmap
	CStatic *pPic = (CStatic*)GetDlgItem(IDC_PICTURE);

	HBITMAP hbmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(), Data.Path.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
	if (hbmp == NULL)
	{
		AfxMessageBox(L"图片加载有误~"); //提示图片加载错误
	}
	
	pPic->SetBitmap(hbmp);
	
//2.使用静态文本控件来限制位图的大小
	CStatic *pPic = (CStatic *)GetDlgItem(IDC_STATICPIC);
	CRect rect;
	pPic->GetWindowRect(&rect);

	HBITMAP hbmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(), Data.Path.c_str(), IMAGE_BITMAP, rect.Width(), rect.Height(), LR_LOADFROMFILE);
	if (hbmp == NULL)
	{
		AfxMessageBox(L"图片加载有误~"); //提示图片加载错误
	}
	pPic->ModifyStyle(NULL, SS_BITMAP); //修改静态文本控件的属性
	pPic->SetBitmap(hbmp);

如果需要重复加载位图,需要注意hbmp位图句柄的资源的释放,否则会内存泄漏

释放的方法也很简单;先判断是否存在绘图句柄,如果存在则先释放再创建,如果不存在则创建,最后退出的时候一定记得要在析构函数中 进行DeleteObject;

if (m_hbmp == NULL)
		{
			m_hbmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(), Data.Path.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		}
		else
		{
			DeleteObject(m_hbmp);
			m_hbmp = (HBITMAP)LoadImage(AfxGetInstanceHandle(), Data.Path.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		}

下面是在做这部分模块时候的一些问题,还有位图字体的旋转 这个简单来说就是先创建一个位图在上面写字,然后将位图拼接到主位图(就是需要添加文字的位图)上;

方案;使用GDI+进行图片的绘制

Q1: 左侧 和 右侧的绘图 如何解决?
=> 主要用到两个函数
graphic.TranslateTransform(30,10); //源点移动到旋转中心
graphic.RotateTransform(90); //旋转
注意:一定要先确定源点位置 然后开始旋转
图形旋转是以放置位置为原点进行顺时针旋转,所以对应的坐标一定要注意
不然可能会出现
Q2: 固定坐标放置文本信息?
=> 方法同上 使用位图拼接来完成
以最开始生成的二维码Bitmap为底,然后在上面添加其他的Bitmap
核心函数:imageGraphics.DrawImage(bitmapRight, 383, 10); //imageGraphics表示原图的Graphic对象,bitmapRight表示添加的位图对象
// 383,10表示位图移动到底位图的坐标
使用GDI+的方法对位图拼接前 一定要把创建的Bitmap进行处理
Bitmap *Whitebit = new Bitmap(Whitex, Whitey);
		for (int x = 0; x < Whitex; x++)
			for (int y = 0; y < Whitey; y++)
				Whitebit->SetPixel(x, y, Color(255, 255, 255));


上面处理的方式 使用setPixel将每个像素点都设置为白色 这样显示出来的位图就不是黑的一块显示出来


配合着函数DrawImage 就可以实现对位图的一个扩展 以及需要遮盖某些区域的内容 都可以这样操作


另外一种方法使用 Clone函数对Bitmap进行“切割”
这里切割的意思是 假如有一个宽高为 200*200的位图 我们需要获取到 200*150的数据 
可以使用如下方法进行位图的操作
存在一个位图 bitmap 这个位图的宽和高为200 现在新的位图获取其中 宽高170*200的区域的内容
int Codex = 200;
int Codey = 200;
Bitmap *bitmapCopy = new Bitmap(Code_x - 30, Code_y);
		Graphics g(bitmapCopy);
		for (int x = 0; x < Code_x - 30; x++)
			for (int y = 0; y < Code_y; y++)
				Whitebit->SetPixel(x, y, Color(255, 255, 255));
		bitmapCopy->Clone(RectF(0, 0, bitmapCopy->GetWidth(), bitmapCopy->GetHeight()), bitmap->GetPixelFormat());
		g.DrawImage(*bitmap, 0, 0);


流程:
首先对原图进行clone 
然后输出指定区域的内容

然后可以得到对应的值 这样就实现对位图进行“切割”操作

如果有问题 欢迎留言指正


猜你喜欢

转载自blog.csdn.net/Wuzm_/article/details/80455857
今日推荐