调用Control DrawToBitmap(Bitmap) 方法是很容易得到控件的图形的 但是bitmap是栅格化图形 栅格化图形有很多缺点 比如文件体积比较大 放大后失真 不易编辑等等 这里教你如何导出一个控件的矢量图
I Windows MetaFile
windows MetaFile 是windows 下面的一种矢量图形格式 事实上WMF 只是记录下来的一串GDI 命令 重新调用一次这一串GDI命令就可以重建之前记录下来的图像 而大部分windows应用程序的界面都是用GDI绘制的 所以理论上都可以导出他们界面的矢量图 详细去看 Windows_Metafile >_Metafile
II 绘图表面 ( drawing surfaces )
用GDI+绘图的时候 基本上你会把图形绘制到 屏幕上的窗体 传到打印机的打印文档 内存里的图像文件等等 这些叫做绘图表面
首先我们来创建一个新的EMF文件
System Drawing Imaging Metafile mf;
Graphics g = control CreateGraphics();
IntPtr hdc = g GetHdc();
mf = new Metafile(hdc new Rectangle( control Width control Height) MetafileFrameUnit Pixel EmfType EmfOnly);
g ReleaseHdc(hdc);
g Dispose();
Graphics g = Graphics FromImage(mf);
调用WinApi把控件打印到此Graphics 对象上面(这个Graphics对象会作为参数传递给下面一级一级的子控件的OnPaint()函数):
const int WM_PRINT = x ;
const int PRF_CHECKVISIBLE = x
PRF_NONCLIENT = x
PRF_CLIENT = x
PRF_ERASEBKGND = x
PRF_CHILDREN = x ;
[DllImport( user dll CharSet = CharSet Auto)]
private static extern IntPtr SendMessage(HandleRef hWnd int msg int wParam int lParam);
public static void DrawControl(Control control Graphics g)
{
if (!control Created)
control CreateControl();
IntPtr hDc = g GetHdc();
SendMessage(new HandleRef(control control Handle) WM_PRINT (int)hDc
(int)(PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT));
g ReleaseHdc(hDc);
}
到这里已经得到了这个控件的矢量图了 下面附加一段代码把这个EMF复制到剪切板上面去
[DllImport( user dll )]
static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport( user dll )]
static extern bool EmptyClipboard();
[DllImport( user dll )]
static extern IntPtr SetClipboardData(uint uFormat IntPtr hMem);
[DllImport( user dll )]
static extern bool CloseClipboard();
[DllImport( gdi dll )]
static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc IntPtr hNULL);
[DllImport( gdi dll )]
static extern bool DeleteEnhMetaFile(IntPtr hemf);
static public bool PutEnhMetafileOnClipboard(IntPtr hWnd Metafile mf)
{
bool bResult = false;
IntPtr hEMF hEMF ;
hEMF = mf GetHenhmetafile(); // invalidates mf
if (!hEMF Equals(new IntPtr( )))
{
hEMF = CopyEnhMetaFile(hEMF new IntPtr( ));
if (!hEMF Equals(new IntPtr( )))
{
if (OpenClipboard(hWnd))
{
if (EmptyClipboard())
{
IntPtr hRes = SetClipboardData( /CF_ENHMETAFILE/ hEMF );
bResult = hRes Equals(hEMF );
CloseClipboard();
}
}
} DeleteEnhMetaFile(hEMF);
} return bResult;
}
lishixinzhi/Article/program/net/201311/13427
MFC控件的标准方法(在控件属性中指定资源ID)是不能显示真彩图像的,其默认最高支持是256色,也就是8bit位图。
通过编程实现在对话框中显示真彩图像有两种方法:
不使用控件,而是直接在对话框的DC上绘制,如果获取的是对话框的DC并通过静态框等获取区域(也可以指定区域),那么你的其它代码不需要改动。
使用控件。获取控件的DC后,因为控件默认是256色,其DC中对Stretch拉伸默认是像素损失模式,因此你的图像会失真。这时就要在拉伸显示之前,重新设置控件的拉伸损失模式为像素接近模式:
pDC->SetStretchBltMode(HALFTONE);
需要注意的是,HALFTONE模式能产生高质量图像,但也是效率最低显示最慢的模式,如果较大或者调用频繁,不建议使用。同时,也应注意在设置HALFTONE模式之后,最好调用SetBrushOrgEx函数以避免出现刷子没对准现象。
另外,获取真彩图像句柄(指针)的方法也有很多,可以使用CImage,也可以使用其他GDI+对象,另外也可以使用解析代码实现。MFC的资源,同样默认是256色,需要特殊的方法才能加载真彩位图。
jpg显示的步骤:
1。打开控件的绘图DC。2。使用OleLoadPicture函数读取jpg图像到内存中。(导入olepro32dll)
3。向DC上绘制图像
示例如下:
CDC pDC = GetDlgItem(IDC_STATIC_IMG)->GetDC(); //获取控件DCHDC hDC = (HDC)pDC;
HANDLE hFile=CreateFile(szImagePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);//从指定的路径szImagePath中读取文件句柄
DWORD dwFileSize=GetFileSize(hFile, NULL); //获得文件的大小,用来分配全局内存
HGLOBAL hImageMemory=GlobalAlloc(GMEM_MOVEABLE, dwFileSize); //给分配全局内存
void pImageMemory=GlobalLock(hImageMemory); //锁定内存
DWORD dwReadedSize; //保存实际读取的文件大小
ReadFile(hFile, pImageMemory, dwFileSize, &dwReadedSize, NULL); //读取到全局内存当中
GlobalUnlock(hImageMemory); //解锁内存
CloseHandle(hFile); //关闭文件句柄
IStream pIStream;//创建一个IStream接口指针,用来保存流
IPicture pIPicture;//创建一个IPicture接口指针,表示对象
CreateStreamOnHGlobal(hImageMemory, false, &pIStream); //用全局内存初使化IStream接口指针
OleLoadPicture(pIStream, 0, false, IID_IPicture, (LPVOID)&(pIPicture));//用OleLoadPicture获得IPicture接口指针
//得到IPicture COM接口对象后,你就可以进行获得信息、显示等 *** 作
OLE_XSIZE_HIMETRIC hmWidth;
OLE_YSIZE_HIMETRIC hmHeight;
pIPicture->get_Width(&hmWidth); //用接口方法获得的宽和高
pIPicture->get_Height(&hmHeight);
pIPicture->Render(hDC,0,0,100,100,0,hmHeight,hmWidth,-hmHeight,NULL); //在指定的DC上绘出
GlobalFree(hImageMemory); //释放全局内存
pIStream->Release(); //释放pIStream
pIPicture->Release(); //释放pIPicture
ReleaseDC(pDC);
以上就是关于如何导出WinForm 控件界面的矢量图全部的内容,包括:如何导出WinForm 控件界面的矢量图、MFC如何在对话框的图片控件中显示真彩色图像、mfc编程如何设置用图片控件动态显示jpg图像。等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)