symbian上自定义的贴图函数

来源:互联网 发布:免费象棋软件排名 编辑:程序博客网 时间:2024/05/02 22:49

 自定义的symbian上的贴图函数及重载函数,并非直接屏幕贴图,而是2个位图合成,位图必须为4k色的格式,增加了切分参数的默认值,减少了函数重载的数量

//可纯贴图并可横向纵向切分的贴图函数,就是可横向纵向平均分割一个图像并选定其中之一进行贴图,分割数要可整除图像宽度,通过调用时是否传递切分参数来控制是否进行切分
void DrawBmp(const TPoint& aPoint, CFbsBitmap* srcBitmap, CFbsBitmap* aBitmap, TInt aSplitColNum=1, TInt aSplitColIndex=0, TInt aSplitRowNum=1, TInt aSplitRowIndex=0 )
{
 DrawBmp( aPoint, srcBitmap , aBitmap, TRect(aBitmap->SizeInPixels()), FALSE, TRgb(0,0,0), aSplitColNum, aSplitColIndex, aSplitRowNum, aSplitRowIndex );
}

//带透明遮罩色并可横向纵向切分的贴图函数,就是目标图中和aMaskColor颜色相同的透明,使用可以正确转为4k色的Rgb色如0xff00ff转为0xf0f,通过调用时是否传递切分参数来控制是否进行切分
void DrawBmp(const TPoint& aPoint, CFbsBitmap* srcBitmap, CFbsBitmap* aBitmap, TRgb aMaskColor, TInt aSplitColNum=1, TInt aSplitColIndex=0, TInt aSplitRowNum=1, TInt aSplitRowIndex=0 )
{
 DrawBmp( aPoint, srcBitmap , aBitmap, TRect(aBitmap->SizeInPixels()), TRUE, aMaskColor, aSplitColNum, aSplitColIndex, aSplitRowNum, aSplitRowIndex );
}

//目标图有选定区域且可横向纵向切分的贴图函数,通过调用时是否传递切分参数来控制是否进行切分
void DrawBmp(const TPoint& aPoint, CFbsBitmap* srcBitmap, CFbsBitmap* aBitmap, const TRect& aRect, TInt aSplitColNum=1, TInt aSplitColIndex=0, TInt aSplitRowNum=1, TInt aSplitRowIndex=0 )
{
 DrawBmp( aPoint, srcBitmap , aBitmap, aRect, FALSE, TRgb(0,0,0), aSplitColNum, aSplitColIndex, aSplitRowNum, aSplitRowIndex );
}

//目标图有选定区域并带透明遮罩色且可横向纵向切分的贴图函数,通过调用时是否传递切分参数来控制是否进行切分
void DrawBmp(const TPoint& aPoint, CFbsBitmap* srcBitmap, CFbsBitmap* aBitmap, const TRect& aRect, TRgb aMaskColor, TInt aSplitColNum=1, TInt aSplitColIndex=0, TInt aSplitRowNum=1, TInt aSplitRowIndex=0 )
{
 DrawBmp( aPoint, srcBitmap , aBitmap, aRect, TRUE, aMaskColor, aSplitColNum, aSplitColIndex, aSplitRowNum, aSplitRowIndex );
}

//完整贴图函数
void DrawBmp(const TPoint& aPoint, CFbsBitmap* srcBitmap , CFbsBitmap* aBitmap, const TRect& aRect, TBool aMask , const TRgb& aMaskColor, TInt aSplitColNum=1, TInt aSplitColIndex=0, TInt aSplitRowNum=1, TInt aSplitRowIndex=0 )
{
 // 锁定
 TBitmapUtil bmpUtil1(srcBitmap);
 TBitmapUtil bmpUtil2(aBitmap);
 bmpUtil1.Begin(TPoint(0,0));
 bmpUtil2.Begin(TPoint(0,0), bmpUtil1); 

 //当横向和纵向的索引值在分割数的范围内才进行贴图
if( aSplitColNum>0 && aSplitColNum>aSplitColIndex && aSplitColIndex>=0 && aSplitRowNum>0 && aSplitRowNum>aSplitRowIndex && aSplitRowIndex>=0 )
 {
  
  TInt width1 = srcBitmap->SizeInPixels().iWidth;   //获得源图宽度
  TInt height1 = srcBitmap->SizeInPixels().iHeight;  //获得源图高度
  TInt width2 = aBitmap->SizeInPixels().iWidth;   //获得目标图宽度
  TInt height2 = aBitmap->SizeInPixels().iHeight;   //获得目标图高度
  
  //选定区域对目标图有效时才进行贴图
  if(aRect.iBr.iX>0 && aRect.iTl.iX<=width2 && aRect.iBr.iY>0 && aRect.iTl.iY<=height2 )
  {
   
   TInt rectfromx = aRect.iTl.iX<0?0:aRect.iTl.iX;     //目标图实际选中区起始X坐标
   TInt rectfromy = aRect.iTl.iY<0?0:aRect.iTl.iY;     //目标图实际选中区起始Y坐标
   
   TInt rectcutw = aRect.iBr.iX>width2?aRect.iBr.iX-width2:0;   //目标图选中区右边被裁宽度
   TInt rectcuth = aRect.iBr.iY>height2?aRect.iBr.iY-height2:0;  //目标图选中区下边被裁高度
   
   TInt width2s=(aRect.iBr.iX-rectfromx-rectcutw)/aSplitColNum;   //获得目标图有效选中区宽度
   TInt height2s=(aRect.iBr.iY-rectfromy-rectcuth)/aSplitRowNum;   //获得目标图有效选中区高度
   
   //目标图有效选中区贴在源图有效区内才进行贴图   
   if( aPoint.iX+width2s>0 && aPoint.iX<=width1 && aPoint.iY+height2s>0 && aPoint.iY<=height1 )
   {
    
    TInt line1 = CFbsBitmap::ScanLineLength(width1, EColor4K) / 2;   //获得源图行长度
    TInt line2 = CFbsBitmap::ScanLineLength(width2, EColor4K) / 2;    //获得目标图行长度
    
    TInt rectx = aPoint.iX<0?0:aPoint.iX;    //源图起始X坐标
    TInt recty = aPoint.iY<0?0:aPoint.iY;    //源图起始Y坐标
    
    TInt fromx = aPoint.iX<0?rectfromx+aSplitColIndex*width2s-aPoint.iX:rectfromx+aSplitColIndex*width2s;  //目标图起始X坐标
    TInt fromy = aPoint.iY<0?rectfromy+aSplitRowIndex*height2s-aPoint.iY:rectfromy+aSplitRowIndex*height2s;  //目标图起始Y坐标
    
    TInt cutw = aPoint.iX+width2s>width1?aPoint.iX+width2s-width1:0;   //目标图右边被裁宽度
    TInt cuth = aPoint.iY+height2s>height1?aPoint.iY+height2s-height1:0;   //目标图下边被裁高度
    
    TInt rectw = rectfromx + width2s * (1 + aSplitColIndex) - fromx - cutw;  //目标图被贴宽度
    TInt recth = rectfromy + height2s * (1 + aSplitRowIndex) - fromy - cuth; //目标图被贴高度
    
    TInt jump1 = line1 - rectw;         //获得源图地址扫描跳跃量
    TInt jump2 = line2 - rectw ;        //获得目标图地址扫描跳跃量
    
    // 获取首地址
    TUint16* addr1 = (TUint16*)srcBitmap->DataAddress();
    TUint16* addr2 = (TUint16*)aBitmap->DataAddress();
    
    // 获取贴图首地址
    TUint16* p1 = addr1 + recty*line1 + rectx;     
    TUint16* p2 = addr2 + fromy*line2 + fromx;     
    
    // 获取贴图末地址
    TUint16* p2end = p2 + line2* (recth - 1) + rectw;
    
    //是否进行透明遮罩
    if(aMask)
    {
     //转换RGB色为TUint16表示的4K色
     TInt maskcolor=aMaskColor.Color4K();
     
     while( p2 < p2end)
     {
      
      TUint16* p2endline = p2 + rectw;
      
      while(p2!=p2endline)
      {
       if( *p2!=maskcolor)
       {
        *p1 = *p2;
       }
       p1++;
       p2++;
      }
      
      p1+=jump1;
      p2+=jump2;
      
     }
    }
    else
    {
     while( p2 < p2end)
     {
      
      TUint16* p2endline = p2 + rectw;
      
      while(p2!=p2endline)
      {
       
       *p1 = *p2;
       
       p1++;
       p2++;
      }
      
      p1+=jump1;
      p2+=jump2;
      
     }
    }
   }
  }
 }
 // 解锁
 bmpUtil2.End();
 bmpUtil1.End();
}

参数说明
const TPoint& aPoint    贴图相对与源图的左上角起始坐标
CFbsBitmap* srcBitmap    源图指针
CFbsBitmap* aBitmap    目标图指针
const TRect& aRect    目标图选定区域
TBool aMask    是否有透明遮罩
const TRgb& aMaskColor    透明遮罩色
TInt aSplitColNum=1    横向切分总数,默认为1,即不切分
TInt aSplitColIndex=0    横向切分索引,默认为0,即横向切分序列中的第一个
TInt aSplitRowNum=1    纵向切分总数,默认为1,即不切分
TInt aSplitRowIndex=0    纵向切分索引,默认为0,即纵向切分序列中的第一个

自己用着还可以,还未发现错误,不知道有无可精简修改之处。如果有人试用可提出意见。
比较繁琐的就是计算源图和目标图坐标的部分,有待优化。
为了减少函数重载的数量设置了切分参数的默认值,不知是否可以进一步减少
另外在横向和纵向分割图像的部分当目标图存在选定区域时为选定有效区域的分割,不知道这种应用较多还是选定区域应该为整个图像分割后选中的部分的有效选定区域?我觉的现在的这种应用较多,这样就可以把多个图像序列整合到一个位图里。

原创粉丝点击