连载:徒手写一个DICOM阅图软件(001)之位图显示

本文介绍了如何使用C++和MFC框架开发一个基础的DICOM阅图软件,首先从实现BMP图像的加载和显示开始,详细讲解了BMP文件格式和在MFC对话框中添加显示代码的过程。

本系列教程是逐步徒手实现一个DICOM阅图软件,采用C++语言,基于MFC的对话框程序来实现。整个实现过程中尽量不用或者少用第三方库、非开源库,主打一个独立自主。

DICOM文件是医学影像标准文件,其组成方式比较简单,就是文件信息头+图像像素数据,这点和BMP图像非常类似,所以作为的教程的第一步,咱们先从实现BMP图像的加载与显示开始。

一、先制作一个BMP图像

打开画图软件,调整画面尺寸是512*512,图像内容任意,颜色选黑白

存储时需要图像存储为256色位图

这个一个8bit的图像,尺寸为512*512,则文件尺寸应该略大于262144( =512*512*1 ),观察生成文件尺寸为263222字节,符合要求。

二、创建一个MFC的对话框程序

其它步骤一路next下去即可。

三、显示图像前的准备工作

先在MFC窗口上删除多余文本框和按钮,然后添加一个“Picture Control”,将其属性中的“Type”改成"Owner Draw",属性“ID”改成"IDC_SHOWIMAGE",顾名思义,这个控件将是我们用来显示图像的窗口。

再在窗口资源上添加一个按钮,ID改成“IDC_LOADDATA”,Caption改成“加载”。

 双击【加载】按钮,IDE会自动生成该按钮的点击函数。

四、BMP文件格式简单介绍

BMP文件由4部分组成:

        1. BMP文件头:BITMAPFILEHEADER,长度14字节

        2. 位图信息头:BITMAPINFOHEADER,长度40字节

        3. 调色板:,长度由索引颜色数决定,如24位以上真彩则没有调色板。

        4. 位图数据:长度为图像的长*宽*位数/8。

五、添加显示代码,显示图像


void CusDicomViewerDlg::OnBnClickedLoaddata( )
{
	CString bmpFilename = L"E:\\TestBmp\\001.bmp"; // 手工制作的bmp文件安放目录

	UCHAR* pBmpBuffer = NULL; // 文件的内容
	int bufLength = 0; // 文件长度

	CFile file; // 打开的文件
	if ( file.Open( bmpFilename, CFile::modeRead|CFile::shareDenyNone) )
	{
		bufLength = ( int )file.GetLength( );
		pBmpBuffer = new UCHAR[bufLength]; // 将文件全部导入内存

		file.Read( pBmpBuffer, bufLength );

		file.Close( );
	}

	BITMAPFILEHEADER* head = ( BITMAPFILEHEADER* )( pBmpBuffer ); // 直接指向文件头
	BITMAPINFOHEADER* info = ( BITMAPINFOHEADER* )( pBmpBuffer + 14 ); // 直接指图像信息
	RGBQUAD* rgbquad = ( RGBQUAD* )( pBmpBuffer + 14 + 40 ); // 

	// 图像预备显示
	UCHAR* pPixelBuffer = pBmpBuffer + 14 + 40 + 256*4; // 直接指向像素数据

	// 进行图像显示
	CWnd* pWnd = GetDlgItem( IDC_SHOWIMAGE ); // 获取到要显示的控件
	if ( pWnd == NULL )
		return;

	CRect rc;
	pWnd->GetClientRect( &rc );
	int imageWidth = rc.Width( );
	int imageHeight = rc.Height( );
	UINT32 *pShowImage = new UINT32[imageWidth*imageHeight]; // 创建一个要显示的内存区域

	// 设置要显示的内容
	for ( int y = 0; y < imageHeight; y++ )
	{
		for ( int x = 0; x < imageWidth; x++ )
		{
			UCHAR c = pPixelBuffer[ x + y * info->biWidth ]; // 取的BMP中每一个像素,为8bit数据
			pShowImage[x + y * imageWidth] = RGB( c, c, c ); // 显示像素为32bit,因为灰度,所以3通道颜色一样。
		}
	}

	CDC* pDC = pWnd->GetDC( );

	CDC mMemDC;
	mMemDC.CreateCompatibleDC( pDC ); // 创建一个内存dc,用于窗口图像重绘时不闪烁
	mMemDC.SetBkMode( TRANSPARENT );

	// 创建临时图像
	CBitmap bitmap;
	bitmap.CreateBitmap( imageWidth,imageHeight,1,
		32, pShowImage );

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

	pDC->BitBlt( 0, 0, imageWidth, imageHeight, &mMemDC, 0, 0, SRCCOPY ); // 窗口绘制

	// 释放信息
	bitmap.DeleteObject( );
	pWnd->ReleaseDC( pDC );


	// 释放内存
	mMemDC.DeleteDC();
	mMemDC.m_hDC = 0;

	if ( pShowImage != NULL )
	{
		delete[] pShowImage;
		pShowImage = NULL;
	}

	if ( pBmpBuffer != NULL )
	{
		delete[] pBmpBuffer;
		pBmpBuffer = NULL;
	}
}

这样,就徒手显示了一个BMP图像

下一篇:

连载:徒手写一个DICOM阅图软件(002)之DICOM图显示-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

优视魔方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值