小弟正在做汉字识别的毕业设计,需要处理不同大小的同一字体,是否能有函数进行放大或缩小(即大小归一化)比如能统一放大成5号体,注意是对位图进行处理,而不是设置字体,请高手们帮帮忙

解决方案 »

  1.   

    http://www.vckbase.com/code/downcode.asp?id=2492
      

  2.   

    放大算法有很多种,主要是插值在里面的应用.
    StretchBlt使用的是邻近插值.插值分为:邻近插值
    双线性插值
    卷积查值
    二元三点插值
    二元全区间插值效果是越来越好,但是计算量是越来越大.
    举其中的一个例子来说:
    双线性插值+   +
      -
    +   +
    将一个图像放大如1.1倍,肯定会出现一些点的坐标不是整数值.目标图像的点和原图像的点也没有一一对应的关系,一般是将放大后的图像坐标除以1.1倍,映射到原来图像里,它不是整数坐标,好象上面那个-号在四个+号中间,考虑这个减号受其它四个象素的影响.越近的影响越大.图像有两个方向,故这种方法叫双线性插值.
      

  3.   

    我写的最简单的
    效果最不好的一种方法BYTE* Zoom( BYTE* pBmpFile , float times , int flag )
    {
    //get info
    int nWidth , nHeight , nNewWidth , nNewHeight , nNewWidthBit , nWidthBit;
    GetInfo( pBmpFile , &nWidth , &nHeight );
    nNewHeight = (int) (nHeight * times);
    nNewWidth = (int) (nWidth * times);
    nNewWidthBit = ( 4 - nNewWidth * 3 % 4 ) % 4 + nNewWidth * 3;
    nWidthBit = ( 4 - nWidth * 3 % 4 ) % 4 + nWidth * 3;
    //excute new size
    int nNewSize = nNewWidthBit * nNewHeight + 54;
    //apply memory
    BYTE* pNewBmpFile=NULL;
    pNewBmpFile = new BYTE [ nNewSize ];
    memset( pNewBmpFile , 0 , nNewSize);
    //create bmp 
    pNewBmpFile = CreateBmp( nNewWidth , nNewHeight , pNewBmpFile );//rewirte bmpdata
    BYTE *pBuf = NULL;
    BYTE *pNewBuf = NULL;
    BYTE *pNewTmp = NULL;
    pBuf = &pBmpFile[54];
    pNewBuf = &pNewBmpFile[54];
    //zoom
    for( int i = 0 ; i < nNewHeight ; i++ )
    {
    pNewTmp = pNewBuf + nNewWidthBit * i;
    for( int j = 0 ; j < nNewWidth * 3 ; j += 3 )
    {
    int offset = i * nNewWidthBit + j;
    CPoint point = OffsettoPixel( offset , nNewWidth , nNewHeight );
    CPoint oldpoint;
    oldpoint.x = (int) (point.x / times);
    oldpoint.y = (int) (point.y / times);
    int oldoffset = PixeltoOffset( oldpoint , nWidthBit , nHeight );
    pNewTmp[j] = pBuf [oldoffset];
    pNewTmp[j+1] = pBuf [oldoffset+1];
    pNewTmp[j+2] = pBuf [oldoffset+2];
    }
    }
    CloseBmp( pBmpFile );
    return pNewBmpFile;
    }
      

  4.   

    用gdi+可以用现成的算发,只要加个参数,就可以实现各种插值。
      

  5.   

    使用函数,
    CBitmap m_bitmap;CDC*pDC=new CDC;
    pDC->SelectObject(&m_bitmap);
    m_bitmap.loadbitmap(IDB_BITMAP1);
    pDC->BitStretch(NULL,0,0,x,y,pDC,xx,yy,0,0);
    设置参数就可以
    自己找点资料好简单的
      

  6.   

    一般都使用插值算法:有近邻取样法,双线形内插法,三次卷积法等。下面是摘自《visual c++ 数字图像与图形处理》的核心代码:
    ///lpbySrcXY----传递源像素(x, y)的地址, 
    //x, y, 经过反向变换后得到的对应于原图像的象点的坐标
    //nScanWidth,  int nScanHeight, 源扫描宽度和扫描高度
    PIXELCOLORRGB CImageGeometry::Interpolate(LPBYTE lpbySrcXY,  int x,  int y,  float fu,  float fv,  int nScanWidth,  int nScanHeight)
    {
    PIXELCOLORRGB rgb; //行字节数, 可以将dwWidthBytes作为参数传递过来
    DWORD dwWidthBytes = (DWORD)nScanWidth * 4;

    switch(m_dwQuality)
    {
    case IMAGE_GEOMETRY_NEAREST_NEIGHBOR_INTERPOLATE :
    {
    BYTE* pbySrc = lpbySrcXY;
    rgb.blue = *pbySrc++;
    rgb.green = *pbySrc++;
    rgb.red = *pbySrc++;
    break;
    }
    case IMAGE_GEOMETRY_BILINEAR_INTERPOLATE :
    {
    //相邻的四个像素最右下角点的x, y坐标偏移量
    int nx = 1;
    int ny = 1;
    if((x + 1) > (nScanWidth - 1)) nx = 0;
    if((y + 1) > (nScanHeight - 1)) ny = 0;

    //相邻四个像素的像素值
    BYTE abyRed[2][2], abyGreen[2][2], abyBlue[2][2];

    //像素点(x, y)的数据位置
    BYTE* pbySrc = lpbySrcXY;
    //获取像素数值.
    //(x, y) = (x, y) + (0, 0)
    abyBlue[0][0] = *pbySrc++;
    abyGreen[0][0] = *pbySrc++;
    abyRed[0][0] = *pbySrc++;

    //(x + 1, y) = (x, y) + (1, 0)
    pbySrc = (lpbySrcXY + nx * 4);
    abyBlue[1][0] = *pbySrc++;
    abyGreen[1][0] = *pbySrc++;
    abyRed[1][0] = *pbySrc++;
    //指向下一行数据
    BYTE* pbySrcTemp = (lpbySrcXY + ny * dwWidthBytes); //(x , y + 1) = (x, y) + (0, 1)
    pbySrc = pbySrcTemp;
    abyBlue[0][1] = *pbySrc++;
    abyGreen[0][1] = *pbySrc++;
    abyRed[0][1] = *pbySrc++; //(x + 1, y + 1) = (x, y) + (1, 1)
    pbySrc = pbySrcTemp + (4 * nx);
    abyBlue[1][1] = *pbySrc++;
    abyGreen[1][1] = *pbySrc++;
    abyRed[1][1] = *pbySrc++;

    rgb.red = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyRed[0][0]) + 
          (1 - fu) * fv * ((float)abyRed[0][1]) + 
      fu * (1 - fv) * ((float)abyRed[1][0]) +
      fu * fv * ((float)abyRed[1][1])), 0, 255));
    rgb.green = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyGreen[0][0]) + 
          (1 - fu) * fv * ((float)abyGreen[0][1]) + 
      fu * (1 - fv) * ((float)abyGreen[1][0]) +
      fu * fv * ((float)abyGreen[1][1])), 0, 255)); rgb.blue = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyBlue[0][0]) + 
          (1 - fu) * fv * ((float)abyBlue[0][1]) + 
      fu * (1 - fv) * ((float)abyBlue[1][0]) +
      fu * fv * ((float)abyBlue[1][1])), 0, 255));
    break;
    }

    case IMAGE_GEOMETRY_THREE_ORDER_INTERPOLATE :
    {
    //像素坐标
    int xx[4], yy[4];
    //相邻四个像素的像素值
    BYTE abyRed[4][4], abyGreen[4][4], abyBlue[4][4]; xx[0] = -1;  xx[1] = 0; xx[2] = 1; xx[3] = 2;
    yy[0] = -1;  yy[1] = 0; yy[2] = 1; yy[3] = 2; //保证合法
    if((x - 1) < 0) xx[0] = 0;
    if((x + 1) > (nScanWidth - 1)) xx[2] = 0;
    if((x + 2) > (nScanWidth - 1)) xx[3] = ((xx[2] == 0) ? 0 : 1); if((y - 1) < 0) yy[0] = 0;
    if((y + 1) > (nScanHeight - 1)) yy[2] = 0;
    if((y + 2) > (nScanHeight - 1)) yy[3] = ((yy[2] == 0) ? 0 : 1); //像素点(x, y)的数据位置
    //获取数据
    int i;
    for(i = 0;i < 4;i++)
    {
    //像素点(x, y)的数据位置
    BYTE* pbySrcBase = lpbySrcXY + yy[i] * dwWidthBytes; for(int j = 0;j < 4;j++)
    {
    BYTE* pbySrc = pbySrcBase + 4 * xx[j];
    abyBlue[i][j] = *pbySrc++;
    abyGreen[i][j] = *pbySrc++;
    abyRed[i][j] = *pbySrc++;
    }
    } //u, v向量
    float afu[4], afv[4]; afu[0] = Sinxx(1.0f + fu);
    afu[1] = Sinxx(fu);
    afu[2] = Sinxx(1.0f - fu);
    afu[3] = Sinxx(2.0f - fu); afv[0] = Sinxx(1.0f + fv);
    afv[1] = Sinxx(fv);
    afv[2] = Sinxx(1.0f - fv);
    afv[3] = Sinxx(2.0f - fv); //矩阵乘向量的中间值
    float afRed[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    float afGreen[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    float afBlue[4] = {0.0f, 0.0f, 0.0f, 0.0f}; for(i = 0;i < 4;i++)
    {
    for(int j = 0;j < 4;j++)
    {
    afRed[i] += afv[j] * abyRed[j][i];
    afGreen[i] += afv[j] * abyGreen[j][i];
    afBlue[i] += afv[j] * abyBlue[j][i];
    }
    }
    rgb.red = (BYTE)(BOUND((afu[0] * afRed[0] + afu[1] * afRed[1] + afu[2] * afRed[2] + 
    afu[3] * afRed[3]), 0, 255));
    rgb.green = (BYTE)(BOUND((afu[0] * afGreen[0] + afu[1] * afGreen[1] + afu[2] * afGreen[2] + 
    afu[3] * afGreen[3]), 0, 255));
    rgb.blue = (BYTE)(BOUND((afu[0] * afBlue[0] + afu[1] * afBlue[1] + afu[2] * afBlue[2] + 
    afu[3] * afBlue[3]), 0, 255));
    break;
    }
    default : break;
    }//end switch return rgb;
    }楼主领会思路即可,希望有所帮助。Good luck.