/******************************************************************
*
*  函数名称:
*      StdDIBbyRect()
*
*  参数:
*     HDIB  hDIB          -图像的句柄
*     int   tarWidth      -标准化的宽度
*     int   tarHeight     -标准化的高度
*
*  返回值:
*         无
*
*  功能:
*     将经过分割的字符,进行缩放处理使他们的宽和高一直,以方便特征的提取
*
*  说明:
*     函数中用到了,每个字符的位置信息,所以必须在执行完分割操作之后才能执行标准化操作
*
******************************************************************/
void StdDIBbyRect(HDIB hDIB, int tarWidth, int tarHeight)
{

//指向图像的指针
BYTE* lpDIB=(BYTE*)::GlobalLock ((HGLOBAL)hDIB);

//指向象素起始位置的指针
BYTE* lpDIBBits=(BYTE*)::FindDIBBits ((char*)lpDIB);

//指向象素的指针
BYTE* lpSrc;

//获取图像的的宽度
LONG lWidth=::DIBWidth ((char*)lpDIB);

//获取图像的高度
LONG lHeight=::DIBHeight ((char*)lpDIB);

// 循环变量
int i;
int j;

// 图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 8);

//宽度、高度方向上的缩放因子
double wscale,hscale;

//开辟一块临时缓存区,来存放变化后的图像信息
LPSTR lpNewDIBBits; LPSTR lpDst;

//缓存区的大小和原图像的数据区大小一样
HLOCAL nNewDIBBits=LocalAlloc(LHND,lLineBytes*lHeight);

//指向缓存区开始位置的指针
lpNewDIBBits=(char*)LocalLock(nNewDIBBits);

//指向缓存内信息的指针
lpDst=(char*)lpNewDIBBits;

//将缓存区的内容赋初始值
memset(lpDst,(BYTE)255,lLineBytes*lHeight);

//进行映射操作的坐标变量
int i_src,j_src;

//存放字符位置信息的Crect对象
CRect rect;
CRect rectnew;

//先清空一个新的矩形区域链表以便存储标准化后的矩形区域链表
m_charRectCopy.clear ();

//从头到尾逐个扫描各个结点
while(!m_charRect.empty())
{
//从表头上得到一个矩形
rect= m_charRect.front();

//从链表头上面删掉一个
m_charRect.pop_front();

//计算缩放因子

//横坐标方向的缩放因子
wscale=(double)tarWidth/rect.Width ();

//纵坐标方向的缩放因子
hscale=(double)tarHeight/rect.Height ();

//计算标准化矩形

//上边界
rectnew.top =rect.top ;

//下边界
rectnew.bottom =rect.top +tarHeight;

//左边界
rectnew.left =rect.left ;

//右边界
rectnew.right =rectnew.left +tarWidth;

//将原矩形框内的象素映射到新的矩形框内
for(i=rectnew.top ;i<rectnew.bottom ;i++)
{
for(j=rectnew.left ;j<rectnew.right ;j++)
{   

//计算映射坐标
i_src=rectnew.top +int((i-rectnew.top )/hscale);
j_src=rectnew.left +int((j-rectnew.left )/wscale);

//将相对应的象素点进行映射操作
lpSrc=(unsigned char *)lpDIBBits + lLineBytes *  i_src + j_src;
lpDst = (char *)lpNewDIBBits + lLineBytes * i + j;
*lpDst=*lpSrc;
}

//将标准化后的矩形区域插入新的链表
m_charRectCopy.push_back (rectnew);

}
}

//存储标准化后新的rect区域
m_charRect=m_charRectCopy;

//将缓存区的内容拷贝到图像的数据区内
memcpy(lpDIBBits,lpNewDIBBits,lLineBytes*lHeight);

//解除锁定
::GlobalUnlock ((HGLOBAL)hDIB);
}
   另外请教一下,我用gdi操作bmp文件时,缩放、拉伸都会使图像失真,本来黑白的图还会出现深浅不一的灰色。有什么好办法解决么?分不够可以加

解决方案 »

  1.   

    直接使用P/Ivoke不行么?public partial class NativeMethods {
        
        /// Return Type: void
        ///hDIB: BYTE*
        ///tarWidth: int
        ///tarHeight: int
        [System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="some")]
    public static extern  void some(ref byte hDIB, int tarWidth, int tarHeight) ;}
      

  2.   

    这只是我在网上找到的一段处理的代码~,怎么P/Ivoke
      

  3.   

    改什么改 多麻烦!
    把你要的功能用C#实现一遍 代码量要比这个小的多,c++好多东西在C#里面哪有那么复杂的转换。
      

  4.   

    我就是用c#写了类似的,但是就是出现那种失真、杂色的问题,我到这个vc++算法好像不会出现这样的问题,才来提问的啥