t

来源:互联网 发布:落地晒衣架知乎 编辑:程序博客网 时间:2024/06/08 03:40

///***************************************************************/          
/*函数名称:Suofang(float xzoom, float yzoom)                                       
/*函数类型:void
/*参数说明:xzoom --水平缩小的比率
/*          yzoom --垂直缩小的比率                                    
/*功能:对图像进行缩放处理。           
/*****************************************************************/
void JiHeBianHuanDib::SuoXiao(float xzoom, float yzoom)
{
    // 源图像的宽度和高度
 LONG wide;                 //这里的宽度和高的是怎样计算的,是以 像素点 计算还是以 存储的字节计算
 LONG height;
 LONG    LineBytes;            //?????????
 // 缩放后图像的宽度和高度
 LONG newwide;
 LONG newheight;
 // 指向源图像的指针
 LPBYTE p_data ;
 LPBYTE  temp;
    temp=this->GetData();   //获得图像的存放的首地址
/* BYTE* CDib::GetData()
{
    return m_pData;
}*/
    p_data= temp;
 // 指向源象素的指针
 LPBYTE lpSrc;
 // 指向缩放图像对应象素的指针
 LPBYTE lpDst;
 // 指向缩放图像的指针 ???????
 LPBYTE hDIB;
 // 循环变量(象素在新DIB中的坐标)
 LONG i;
 LONG j;
 // 象素在源DIB中的坐标
 LONG i0;
 LONG j0;
 if(m_pBitmapInfoHeader->biBitCount<9)  //灰度图像
 {
  // 获取图像的宽度
  wide = this->GetWidth();
  LineBytes=(wide*8+31)/32*4;
  // 获取图像的高度
  height = this->GetHeight();
  // 计算缩放后的图像实际宽度和高度
  // 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分
  newwide = (LONG) (wide * xzoom  + 0.5);
  newheight = (LONG) (height * yzoom  + 0.5);
  // 分配内存,以保存新DIB
  hDIB = new BYTE[ newwide * newheight*3 ];
  int k1 =int(yzoom+ 0.5);
  int k2 =int(xzoom+ 0.5);
  // 针对图像每行进行操作
  for(j = 0; j < height-1; j=j+k1)
  {
   // 针对图像每列进行操作
   for(i = 0; i < wide-1; i=i+k2)
   {
    // 指向新DIB第i行,第j个象素的指针
    // 注意此处宽度和高度是新DIB的宽度和高度
    lpDst = (LPBYTE)hDIB  + newwide * j + i;
    // 计算该象素在源DIB中的坐标
    j0 = (LONG) (j / yzoom  + 0.5);
    i0 = (LONG) (i / xzoom  + 0.5);
    // 判断是否在源图范围内
    if( (i0 >= 0) && (i0 < wide) && (j0 >= 0) && (j0 < height))
    {
     // 指向源DIB第i0行,第j0个象素的指针
     lpSrc = (LPBYTE)p_data + wide * j0 + i0;
     // 复制象素
     *lpDst = *lpSrc;
    }
    else
    {
     // 对于源图中没有的象素,直接赋值为255
     *lpDst = 255;
    }
   }
  }
  // 复制缩小后的图像
  for(j=0;j<height;j++)
  { 
   for(i=0;i<wide;i++)
   {
    if(j<=newheight&&i<=newwide)
    {
     lpDst = (LPBYTE)hDIB  + newwide * j + i;
     *p_data=*lpDst;      
    }
    else *p_data=255;
    p_data++;
   }
  }    
  delete hDIB;
 }
 else //24位彩色
 {
  // 获取图像的宽度
  wide = this->GetDibWidthBytes();
  
  LineBytes = (((wide * 8)+31)/32*4);

 
  //读取图片时候行字节数的算法 
  //已知:LineBytes是整型。width为bmp图像的宽度,以像素为单位。

  /*该算法为:LineBytes = (width * bitCount + 31) / 32 * 4  bitCount为位图位宽,
  32位BMP,位宽为32、24位BMP位宽为23、256色位图位宽为8、等等。
  这是一种对齐算法,对于BMP等位图来说,要求是4字节对齐,
  即每行字节数必须为4的整数倍。因为8bit等于1Byte,
  同时满足以4字节为对齐单位向下对齐,
  所以可以得:LineBytes = (width * bitCount / 8 + 3) / 4 * 4对于位宽不足8的位图,
  有可能是多个像素才占用1Byte,所以应该将“/ 8”移出括号,
  进一步得:LineBytes = (width * bitCount + 31) / 32 * 4*/

 


  // 获取图像的高度
  height = this->GetHeight();

  CString str;
  str.Format("w=%d h=%d l=%d",wide,height,LineBytes);
  AfxMessageBox(str);
  // 计算缩放后的图像实际宽度
  // 此处直接加0.5是由于强制类型转换时不四舍五入,而是直接截去小数部分
  newwide = (LONG) (LineBytes * xzoom  + 0.5);
  // 计算缩放后的图像高度
  newheight = (LONG) (height * yzoom  + 0.5);
  // 分配内存,以保存新DIB
  hDIB = new BYTE[ newwide * newheight*3 ];  //计算得到新位图所需要的内存单元的大小
 // int k1 =(int)(yzoom+ 0.5);
 // int k2 =(int)(xzoom+ 0.5);//向下取整?????????????

  int k1=1;
  int k2=1;
  // 针对图像每行进行操作
  for(j = 0; j < height-1; j=j+k1)
  {
   // 针对图像每列进行操作
   for(i = 0; i < LineBytes-1; i=i+k2*3)//i=i+k2*3 ?????
   {
    // 指向新DIB第i行,第j个象素的指针
    // 注意此处宽度和高度是新DIB的宽度和高度
    lpDst = (LPBYTE)hDIB  + newwide * j + i;   
    // 计算该象素在源DIB中的坐标
    j0 = (LONG) (j / yzoom  + 0.5);
    i0 = (LONG) (i / xzoom  + 0.5);
    // 判断是否在源图范围内
    if( (i0 >= 0) && (i0 < LineBytes) && (j0 >= 0) && (j0 < height))
    {    
     // 指向源DIB第i0行,第j0个象素的指针
     lpSrc = (LPBYTE)p_data + LineBytes * j0 + i0;
     // 复制象素
     *lpDst = *lpSrc;          //每个像素三个内存单元,  都要复制到目的内存的
     *(lpDst+1)=*(lpSrc+1);
     *(lpDst+2)=*(lpSrc+2);              
    }
    else
    {
     // 对于源图中没有的象素,直接赋值为255
     *lpDst = 255;
    }
   }
  }
  // 复制缩小后的图像
  for(j=0;j<height;j++)
  { 
   for(i=0;i<LineBytes;i++)
   {
    if(j<=newheight&&i<=newwide)
    {
     //if(i<LineBytes*xzoom/3)
     //if(i>LineBytes*xzoom/3&&i<2*LineBytes*xzoom/3)  //添加的   中间的图像
    // if(i>2*LineBytes*xzoom/3)
     {
     lpDst = (LPBYTE)hDIB  + newwide * j + i;
     *p_data=*lpDst;
     }
    // else
    // {
    //  *p_data=255;  //添加的
    // }
    
    }
    else *p_data=255;
    
    p_data++;
   }
  }

 

  
 }
}

原创粉丝点击