zoukankan      html  css  js  c++  java
  • OpenCV实现图像上添加汉字 转

    <span style="font-size:18px;">void GetStringSize(HDC hDC, const char* str, int* w, int* h)
    {
        SIZE size;
        GetTextExtentPoint32A(hDC, str, strlen(str), &size);
        if(w != 0) *w = size.cx;
        if(h != 0) *h = size.cy;
    }
    
    void paDrawString(Mat& dst, const char* str, Point org, Scalar color, int fontSize, bool italic, bool underline)
    {
        CV_Assert(dst.data != 0 && (dst.channels() == 1 || dst.channels() == 3));
    
        int x, y, r, b;
        if(org.x > dst.cols || org.y > dst.rows) return;
        x = org.x < 0 ? -org.x : 0;
        y = org.y < 0 ? -org.y : 0;
    
        LOGFONTA lf;
        lf.lfHeight         = - fontSize ;
        lf.lfWidth          = 0 ;
        lf.lfEscapement     = 0 ;
        lf.lfOrientation    = 0 ;
        lf.lfWeight         = 5;
        lf.lfItalic         = italic ;    //斜体
        lf.lfUnderline      = underline ;    //下划线
        lf.lfStrikeOut       = 0 ;
        lf.lfCharSet        = DEFAULT_CHARSET ;
        lf.lfOutPrecision    = 0 ;
        lf.lfClipPrecision    = 0 ;
        lf.lfQuality         = PROOF_QUALITY ;
        lf.lfPitchAndFamily  = 0 ;
        strcpy (lf.lfFaceName, "华文行楷" );
    
        HFONT hf = CreateFontIndirectA(&lf);
        HDC hDC = CreateCompatibleDC(0);
        HFONT hOldFont = (HFONT)SelectObject(hDC, hf);
    
        int strBaseW = 0, strBaseH = 0;
        int singleRow = 0;
        char buf[1 << 12];
        strcpy(buf, str);
    
        //处理多行
        {
            int nnh = 0;
            int cw, ch;
            const char* ln = strtok(buf, "
    ");
            while(ln != 0)
            {
                GetStringSize(hDC, ln, &cw, &ch);
                strBaseW = max(strBaseW, cw);
                strBaseH = max(strBaseH, ch);
    
                ln = strtok(0, "
    ");
                nnh++;
            }
            singleRow = strBaseH;
            strBaseH *= nnh;
        }
    
        if(org.x + strBaseW < 0 || org.y + strBaseH < 0)
        {
            SelectObject(hDC, hOldFont);
            DeleteObject(hf);
            DeleteObject(hDC);
            return;
        }
    
        r = org.x + strBaseW > dst.cols? dst.cols - org.x - 1 : strBaseW - 1;    
        b = org.y + strBaseH > dst.rows ? dst.rows - org.y - 1 : strBaseH - 1;
        org.x = org.x < 0 ? 0 : org.x;
        org.y = org.y < 0 ? 0 : org.y;
    
        BITMAPINFO bmp = {0};
        BITMAPINFOHEADER& bih = bmp.bmiHeader;
        int strDrawLineStep = strBaseW * 3 % 4 == 0 ? strBaseW * 3 : (strBaseW * 3 + 4 - ((strBaseW * 3) % 4));
    
        bih.biSize=sizeof(BITMAPINFOHEADER);
        bih.biWidth=strBaseW;
        bih.biHeight=strBaseH;
        bih.biPlanes=1;
        bih.biBitCount=24;
        bih.biCompression=BI_RGB;
        bih.biSizeImage=strBaseH * strDrawLineStep;
        bih.biClrUsed=0;
        bih.biClrImportant=0;
    
        void* pDibData = 0;
        HBITMAP hBmp = CreateDIBSection(hDC, &bmp, DIB_RGB_COLORS, &pDibData, 0, 0);
    
        CV_Assert(pDibData != 0);
        HBITMAP hOldBmp = (HBITMAP)SelectObject(hDC, hBmp);
    
        //color.val[2], color.val[1], color.val[0]
        SetTextColor(hDC, RGB(255, 255, 255));
        SetBkColor(hDC, 0);
        //SetStretchBltMode(hDC, COLORONCOLOR);
    
        strcpy(buf, str);
        const char* ln = strtok(buf, "
    ");
        int outTextY = 0;
        while(ln != 0)
        {
            TextOutA(hDC, 0, outTextY, ln, strlen(ln));
            outTextY += singleRow;
            ln = strtok(0, "
    ");
        }
        uchar* dstData = (uchar*)dst.data;
        int dstStep = dst.step/sizeof(dstData[0]);
        unsigned char* pImg = (unsigned char*)dst.data + org.x * dst.channels() + org.y * dstStep;
        unsigned char* pStr = (unsigned char*)pDibData + x * 3;
        for(int tty = y; tty <= b; ++tty)
        {
            unsigned char* subImg = pImg + (tty - y) * dstStep;
            unsigned char* subStr = pStr + (strBaseH - tty - 1) * strDrawLineStep;
            for (int ttx = x; ttx <= r; ++ttx)
            {
                for (int n = 0; n < dst.channels(); ++n){
                    double vtxt = subStr[n] / 255.0;
                    int cvv =  vtxt * color.val[n] + (1 - vtxt) * subImg[n];
                    subImg[n] = cvv > 255 ? 255 : (cvv < 0 ? 0 : cvv);
                }
    
                subStr += 3;
                subImg += dst.channels();
            }
        }
    
        SelectObject(hDC, hOldBmp);
        SelectObject(hDC, hOldFont);
        DeleteObject(hf);
        DeleteObject(hBmp);
        DeleteDC(hDC);
    }

    主函数

    void main()
    {
        Mat img = imread("cat.jpg");
        if(!img.data)
        {
            cout<<"load image error"<<endl;
            return;
        }
        paDrawString(img, "测试汉字哈...
    换行了哟
    真的可以啊!!!~",Point(10, 10), Scalar(255,0,0), 50, true, true);
        imshow("img", img);
        waitKey();
    }
  • 相关阅读:
    【初学EXT】布局练习
    创建型模式总结(补充UML类图)
    数据库基本概念总结
    Word2010操作技巧总结
    VMWare虚拟机磁盘压缩和上网总结
    第一次用word2010发布文章到博客园记
    设计模式学习总结一原则及创建型模式
    为什么要开始写blog?
    Delphi异常处理总结
    设计模式总结之行为型模式
  • 原文地址:https://www.cnblogs.com/love6tao/p/6882024.html
Copyright © 2011-2022 走看看