转自:http://blog.csdn.net/xuefengdage/article/details/49447897
采用freetype库,写小字会失真,网上找到这个,利用HDC直接写,效果很好,做个摘抄。
1 <span style="font-size:18px;">void GetStringSize(HDC hDC, const char* str, int* w, int* h) 2 { 3 SIZE size; 4 GetTextExtentPoint32A(hDC, str, strlen(str), &size); 5 if(w != 0) *w = size.cx; 6 if(h != 0) *h = size.cy; 7 } 8 9 void paDrawString(Mat& dst, const char* str, Point org, Scalar color, int fontSize, bool italic, bool underline) 10 { 11 CV_Assert(dst.data != 0 && (dst.channels() == 1 || dst.channels() == 3)); 12 13 int x, y, r, b; 14 if(org.x > dst.cols || org.y > dst.rows) return; 15 x = org.x < 0 ? -org.x : 0; 16 y = org.y < 0 ? -org.y : 0; 17 18 LOGFONTA lf; 19 lf.lfHeight = - fontSize ; 20 lf.lfWidth = 0 ; 21 lf.lfEscapement = 0 ; 22 lf.lfOrientation = 0 ; 23 lf.lfWeight = 5; 24 lf.lfItalic = italic ; //斜体 25 lf.lfUnderline = underline ; //下划线 26 lf.lfStrikeOut = 0 ; 27 lf.lfCharSet = DEFAULT_CHARSET ; 28 lf.lfOutPrecision = 0 ; 29 lf.lfClipPrecision = 0 ; 30 lf.lfQuality = PROOF_QUALITY ; 31 lf.lfPitchAndFamily = 0 ; 32 strcpy (lf.lfFaceName, "华文行楷" ); 33 34 HFONT hf = CreateFontIndirectA(&lf); 35 HDC hDC = CreateCompatibleDC(0); 36 HFONT hOldFont = (HFONT)SelectObject(hDC, hf); 37 38 int strBaseW = 0, strBaseH = 0; 39 int singleRow = 0; 40 char buf[1 << 12]; 41 strcpy(buf, str); 42 43 //处理多行 44 { 45 int nnh = 0; 46 int cw, ch; 47 const char* ln = strtok(buf, " "); 48 while(ln != 0) 49 { 50 GetStringSize(hDC, ln, &cw, &ch); 51 strBaseW = max(strBaseW, cw); 52 strBaseH = max(strBaseH, ch); 53 54 ln = strtok(0, " "); 55 nnh++; 56 } 57 singleRow = strBaseH; 58 strBaseH *= nnh; 59 } 60 61 if(org.x + strBaseW < 0 || org.y + strBaseH < 0) 62 { 63 SelectObject(hDC, hOldFont); 64 DeleteObject(hf); 65 DeleteObject(hDC); 66 return; 67 } 68 69 r = org.x + strBaseW > dst.cols? dst.cols - org.x - 1 : strBaseW - 1; 70 b = org.y + strBaseH > dst.rows ? dst.rows - org.y - 1 : strBaseH - 1; 71 org.x = org.x < 0 ? 0 : org.x; 72 org.y = org.y < 0 ? 0 : org.y; 73 74 BITMAPINFO bmp = {0}; 75 BITMAPINFOHEADER& bih = bmp.bmiHeader; 76 int strDrawLineStep = strBaseW * 3 % 4 == 0 ? strBaseW * 3 : (strBaseW * 3 + 4 - ((strBaseW * 3) % 4)); 77 78 bih.biSize=sizeof(BITMAPINFOHEADER); 79 bih.biWidth=strBaseW; 80 bih.biHeight=strBaseH; 81 bih.biPlanes=1; 82 bih.biBitCount=24; 83 bih.biCompression=BI_RGB; 84 bih.biSizeImage=strBaseH * strDrawLineStep; 85 bih.biClrUsed=0; 86 bih.biClrImportant=0; 87 88 void* pDibData = 0; 89 HBITMAP hBmp = CreateDIBSection(hDC, &bmp, DIB_RGB_COLORS, &pDibData, 0, 0); 90 91 CV_Assert(pDibData != 0); 92 HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp); 93 94 //color.val[2], color.val[1], color.val[0] 95 SetTextColor(hDC, RGB(255, 255, 255)); 96 SetBkColor(hDC, 0); 97 //SetStretchBltMode(hDC, COLORONCOLOR); 98 99 strcpy(buf, str); 100 const char* ln = strtok(buf, " "); 101 int outTextY = 0; 102 while(ln != 0) 103 { 104 TextOutA(hDC, 0, outTextY, ln, strlen(ln)); 105 outTextY += singleRow; 106 ln = strtok(0, " "); 107 } 108 uchar* dstData = (uchar*)dst.data; 109 int dstStep = dst.step/sizeof(dstData[0]); 110 unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep; 111 unsigned char* pStr = (unsigned char*)pDibData + x * 3; 112 for(int tty = y; tty <= b; ++tty) 113 { 114 unsigned char* subImg = pImg + (tty - y) * dstStep; 115 unsigned char* subStr = pStr + (strBaseH - tty - 1) * strDrawLineStep; 116 for (int ttx = x; ttx <= r; ++ttx) 117 { 118 for (int n = 0; n < dst.channels(); ++n){ 119 double vtxt = subStr[n] / 255.0; 120 int cvv = vtxt * color.val[n] + (1 - vtxt) * subImg[n]; 121 subImg[n] = cvv > 255 ? 255 : (cvv < 0 ? 0 : cvv); 122 } 123 124 subStr += 3; 125 subImg += dst.channels(); 126 } 127 } 128 129 SelectObject(hDC, hOldBmp); 130 SelectObject(hDC, hOldFont); 131 DeleteObject(hf); 132 DeleteObject(hBmp); 133 DeleteDC(hDC); 134 }