#QT利用freetype提取字库图片

这是某个项目中要用到的片段,结合上一篇文章#QT从字体名获取字库文件路径使用

// 保存位图
int SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
{
	HDC                 hDC;
	int                 iBits;
	WORD                wBitCount;

    DWORD               dwPaletteSize=0,dwBmBitsSize,dwDIBSize,   dwWritten;
    BITMAP              Bitmap;
    BITMAPFILEHEADER    bmfHdr;
    BITMAPINFOHEADER    bi;
    LPBITMAPINFOHEADER  lpbi;
    HANDLE         		fh, hDib, hPal,hOldPal=NULL;
   
      //计算位图文件每个像素所占字节数
    hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
	iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
    DeleteDC(hDC);
	
    if(iBits <= 1)
    wBitCount   =   1;
    else if(iBits <= 4)
		wBitCount   =   4;
    else if(iBits  <= 8)
		wBitCount=8;
    else if(iBits <= 24)
		wBitCount = 24;
    
	//计算调色板大小
	if(wBitCount <= 8)
		dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);
     
    //设置位图信息头结构
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
    bi.biSize			= sizeof(BITMAPINFOHEADER);
    bi.biWidth			= Bitmap.bmWidth;
    bi.biHeight			= Bitmap.bmHeight;
    bi.biPlanes			= 1;
    bi.biBitCount		= wBitCount;
    bi.biCompression	= BI_RGB;
    bi.biSizeImage		= 0;
    bi.biXPelsPerMeter	= 0;
    bi.biYPelsPerMeter	= 0;
    bi.biClrUsed		= 0;
    bi.biClrImportant	= 0;

	dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 *Bitmap.bmHeight;
	
	//为位图内容分配内存
	hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
	lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
    *lpbi = bi;
	
    //处理调色板      
	hPal = GetStockObject(DEFAULT_PALETTE);
    if(hPal)
    {
		hDC = GetDC(NULL);
		hOldPal = SelectPalette(hDC, hPal, FALSE);
		RealizePalette(hDC);
    }
	
    //获取该调色板下新的像素值
    GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize,(BITMAPINFOHEADER *)lpbi, DIB_RGB_COLORS);    
    if(hOldPal)
	{
		SelectPalette(hDC, hOldPal, TRUE);
		RealizePalette(hDC);
		ReleaseDC(NULL, hDC);
	}
    
	//创建位图文件        
	fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if(fh == INVALID_HANDLE_VALUE)
		return FALSE;
    
	//设置位图文件头
    bmfHdr.bfType = 0x4D42;
	dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;    
	bmfHdr.bfSize = dwDIBSize;
	bmfHdr.bfReserved1 = 0;
	bmfHdr.bfReserved2 = 0;
	bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;

	WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
    WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
     
    GlobalUnlock(hDib);
    GlobalFree(hDib);
    CloseHandle(fh);
}

// HDC裁剪图片
HBITMAP xGetBitmap(HDC hDCSrc, HBITMAP hBitmapSrc, int x, int y, int nWidth, int nHeight)
{
	HDC		hDC = NULL;
	HDC		hMemDC = NULL;
	HBITMAP	hTarget = NULL;
	HGDIOBJ	pOldBmpTag = NULL;
	HGDIOBJ	pOldBmpSrc = NULL;
	
	if(hDCSrc == NULL || hBitmapSrc == NULL)
		return NULL;
	
	hDC = ::GetDC(NULL);
	hMemDC = ::CreateCompatibleDC(hDC);
	hTarget = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
	pOldBmpTag = ::SelectObject(hMemDC, hTarget);
	pOldBmpSrc = ::SelectObject(hDCSrc, hBitmapSrc);
	::BitBlt(hMemDC, 0, 0, nWidth, nHeight, x, y, SRCCOPY);
	::SelectObject(hMemDC, pOldBmpTag);
	::SelectObject(hDCSrc, pOldBmpSrc);
	::DeleteObject(pOldBmpTag);
	::DeleteObject(pOldBmpSrc);
	::DeleteDC(hDCSrc);
	::DeleteDC(hMemDC);
	::ReleaseDC(NULL, hDC);
	return hTarget;
}


// iCharSize	字号大小
// uCode		文字unicode编码
int GetCharBitmap(int iCharSize, ushort uCode)
{
	FT_Library		ftLibrary;
	FT_Face			ftFace;
	FT_UInt			uiGlyphIndex = 0;
	FT_Error		ftError = FT_Init_FreeType(&ftLibrary);
	
	if(ftError)
	{
		printf("FT_Init_FreeType failed.\n");
		return -1;
	}
	
	ftError = FT_New_Face(ftLibrary, "C:\\Windows\\Fonts\\simsum.ttc", 0, &ftFace);
	if(ftError == FT_Err_Unknown_File_Format)
	{
		printf("FT_New_Face could not support this format file.\n");
		return -1;
	}
	else if(ftError)
	{
		printf("FT_New_Face could not open file: %s\n");
		return -1;
	}
	
	ftError = FT_Set_Pixel_Sizes(ftFace, iCharSize, 0);
	if(ftError)
	{
		printf("FT_Set_Pixel_Sizes failed.\n");
		return -1;
	}
	
	uiGlyphIndex = FT_Get_Char_Index(ftFace, uCode);
	if(uiGlyphIndex == 0)
	{
		printf("FT_Get_Char_Index could not found this char.\n");
		return -1;
	}
	
	FT_Load_Glyph(ftFace, uCode, FT_LOAD_DEFAULT);
	FT_Render_Glyph(ftFace->glyph, FT_RENDER_MODE_MOMO);
	
	// 以下为Win32截图
	uint	iRow = 0, iCol = 0, p, q;
	int		nWidth = ftFace->glyph->bitmap.width;
	int		nHeight = ftFace->glyph->bitmap.rows;
	HDC		hDC = ::GetDC(0);
	HDC		hMemDC = ::CreateCompatibleDC(hDC);
	HBITMAP	hBitmap = ::CreateCompatibleBitmap(hDC, nWidth, nHeight);
	HBITMAP	hOldBmp = (HBITMAP)::SelectObject(hMemDC, hBitmap);
	HBITMAP	hOutput;
	
	for(iRow = 0; iRow < ftFace->glyph->bitmap.rows; iRow++)
	{
		for(iCol = 0; iCol < ftFace->glyph->bitmap.width; iCol++)
		{
			if(ftFace->glyph->bitmap.buffer[iRow * ftFace->glyph->bitmap.pitch + iCol / 8] & (0xC0 >> (iCol % 8))) == 0)
			{
				::SetPixel(hMemDC, iCol, iRow, RGB(0, 0, 0));
			}
			else
			{
				::SetPixel(hMemDC, iCol, iRow, RGB(255, 0, 0));
			}
		}
	}
	
	::SelectObject(hMemDC, hOldBmp);
	hOutput = GetBitMap(hMemDC, hBitmap, 0, 0, nWidth, nHeight);
	if(hOutput)
	{
		SaveBitmapToFile(hOutput, "test.bmp");
		::DeleteObject(hOutput);
	}
	
	::DeleteObject(hBitmap);
	::DeleteObject(hMemDC);
	::ReleaseDC(NULL, hDC);
	return 1;
}


void RunTest()
{
	USHORT		uChar = 0x4E2D;	// 中
	int			nSize = 128;
	GetCharBitmap(nSize, uChar);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

汪宁宇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值