如果要实现--画中画,图片合并,OSD,跨平台等,那么,SDL是个很好的选择!



#ifndef _TSDL_OSD_IMAGE_MERGE_HPP_
#define _TSDL_OSD_IMAGE_MERGE_HPP_


enum TFontStyle
{
    STYLE_TTF_NORMAL        =0x00,
    STYLE_TTF_BOLD          =0x01,
    STYLE_TTF_ITALIC        =0x02,
    STYLE_TTF_UNDERLINE     =0x04,
    STYLE_TTF_STRIKETHROUGH =0x08
};


enum TRenderType
{
    TYPE_SOLID,
    TYPE_SHADED,
    TYPE_BLENDED
};


typedef struct TColor
{
    unsigned char r;
    unsigned char g;
    unsigned char b;
    unsigned char a;
} TColor;








class TSDL_SURFACE_IMAGE;
class TSDL_SURFACE_IMAGE;
class TXImage{
public:
    TXImage();
    virtual ~TXImage();
public:
    int saveimagepng(const char *file);
    int saveimagebmp(const char *file);
    int mergeimage(int x,int y,TXImage *src);
    int mergeimageScaled(int x,int y,int w,int h,TXImage *src);


public:
    unsigned  int getwidth() ;
    unsigned  int getheight();
public:
    TSDL_SURFACE_IMAGE *getimage();
    unsigned  char *getrgbdata();
    unsigned  char *getrgbframe();
    unsigned  char *getyuvframe();
protected:
    unsigned  int fwidth ;
    unsigned  int fheight;
protected:
    TSDL_SURFACE_IMAGE *fimage;
    unsigned char *fyuvframe;
    unsigned char *frgbframe;
protected:




};








class TXrgbimage :public TXImage{
public:
    TXrgbimage(unsigned int width = 1280, unsigned int height = 1080,TColor color={255,255,255,255},unsigned int alpha = 255);
    virtual ~TXrgbimage();
protected:




};




class TXrgbmemimage :public TXImage{
public:
    TXrgbmemimage(void *pixels,unsigned int width = 1280, unsigned int height = 1080,unsigned int alpha = 255);
    virtual ~TXrgbmemimage();
protected:


};




class TXyuvmemimage :public TXImage{
public:
    TXyuvmemimage(void *pixels,unsigned int width = 1280, unsigned int height = 1080,unsigned int alpha = 255);
    virtual ~TXyuvmemimage();
protected:




};




class TXlocalfileimage :public TXImage{
public:
    TXlocalfileimage(const char *filename,unsigned int alpha = 255);
    virtual ~TXlocalfileimage();
protected:




};




class TXttfimage :public TXImage{
public:
    TXttfimage(const char *fontfile,const char *text, TColor fgcolor={0,0,0,0},TColor bgcolor={100,100,100,0},unsigned int fontsize = 20,TFontStyle fontstyle = TFontStyle::STYLE_TTF_NORMAL,TRenderType rendertype = TRenderType::TYPE_SOLID,unsigned int alpha = 255 );
    virtual ~TXttfimage();
protected:




};





#endif //_TSDL_OSD_IMAGE_MERGE_HPP_





#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "Tsdlmerge.hpp"




using namespace std ;




class TSDL_IMAGE_MERGE_TOOLS{
public:
    static void CONVERT_RGB24_TO_BGR24(unsigned char *rgb24,unsigned int width,unsigned int height);
    static unsigned char CONVERT_ADJUST(double tmp);
    static void CONVERT_YUV420P_TO_RGB24(unsigned char *yuvbuf,unsigned char *rgbbuf,unsigned int width,unsigned int height);
    static void CONVERT_RGB24_TO_YUV420P(unsigned char *rgbbuf,  unsigned char *yuvbuf,unsigned int width, unsigned int height);


    static bool CONVERT_RGB_MIRRORR(unsigned char *rgb, unsigned long lWidth, unsigned long lHeight, unsigned  int bpp = 24,bool isDirect = false);
    static bool CONVERT_RGB__HORIZONTAL(unsigned char *rgb, unsigned int width, unsigned int height);




    static void CONVERT_RGBA32_MERGE_IMAGE(
            unsigned char *rgb_dst,
            unsigned int width_dst,
            unsigned int height_dst,
            unsigned char *rgb_src,
            unsigned int width_src,
            unsigned int height_src,
            unsigned int lx,
            unsigned int ly,
            unsigned int bpp = 24,
            unsigned int alpha = 0
    );




    static void CONVERT_SAVE_RGB_IMAGE(
            const char *filename,
            unsigned char *rgb,
            unsigned int width,
            unsigned  int height,
            unsigned int bpp);




};






bool TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB_MIRRORR(unsigned char *rgb, unsigned long lWidth, unsigned long lHeight, unsigned  int bpp,bool isDirect)
{
    bool flag = false;
    unsigned char *lpBits = NULL;                     // 指向复制图像的指针
    do
    {
        if((NULL == rgb)||(0 == lHeight)||(0 == lWidth)){
            break;
        }


        unsigned char *   lpSrc;                      // 指向源图像的指针
        unsigned char *   lpDst;                      // 指向要复制区域的指针
        //unsigned char *   lpBits;                     // 指向复制图像的指针
        unsigned long    i;                          // 循环变量
        unsigned long    j;
        unsigned long lLineBytes;                    // 图像每行的字节数


        lLineBytes = lWidth * bpp / 8 ;// 计算图像每行的字节数


        lpBits = new unsigned char [lLineBytes];
        if(NULL == lpBits){
            break;
        }


        // 判断镜像方式
        if (isDirect)     // 水平镜像
        {
            // 针对图像每行进行操作
            for(i = 0; i < lHeight; i++)
            {
                // 针对每行图像左半部分进行操作
                for(j = 0; j < lWidth / 2; j++)
                {
                    // 指向倒数第i行,第j个象素的指针
                    lpSrc = (unsigned char *)rgb + lLineBytes * i + j;
                    // 指向倒数第i行,倒数第j个象素的指针
                    lpDst = (unsigned char *)rgb + lLineBytes * (i + 1) - j;


                    // 备份一个象素
                    *lpBits = *lpDst;


                    // 将倒数第i行,第j个象素复制到倒数第i行,倒数第j个象素
                    *lpDst = *lpSrc;
                    // 将倒数第i行,倒数第j个象素复制到倒数第i行,第j个象素
                    *lpSrc = *lpBits;
                }
            }
        }
        else                // 垂直镜像
        {
            // 针对上半图像进行操作
            for(i = 0; i < lHeight / 2; i++)
            {
                // 指向倒数第i行象素起点的指针
                lpSrc = (unsigned char *)rgb + lLineBytes * i;
                // 指向第i行象素起点的指针
                lpDst = (unsigned char *)rgb + lLineBytes * (lHeight - i - 1);


                // 备份一行,宽度为lWidth
                memcpy(lpBits, lpDst, lLineBytes);


                // 将倒数第i行象素复制到第i行
                memcpy(lpDst, lpSrc, lLineBytes);
                // 将第i行象素复制到倒数第i行
                memcpy(lpSrc, lpBits, lLineBytes);
            }
        }


        flag = true;




    }while(false);


    if(NULL != lpBits){
        delete[] lpBits;
    }




    return flag ;






}




bool TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB__HORIZONTAL(unsigned char *rgb, unsigned int width, unsigned int height)
{
    bool flag = false;
    unsigned char *prgbtmp  = NULL;
    do
    {
        // 输入参数合法性判断
        if((rgb == NULL)|| (0 == width)||(0 == height)){
            break;
        }


        // 每行图像数据的字节数
        int iLBytes  = (width*24+31)/32*4;
        int itmp     = iLBytes*height;


        // 临时RGB图像指针
        prgbtmp  = (unsigned char*)malloc(itmp); // itmp = iLBytes*iHeight;
        if(NULL == prgbtmp){
            break;
        }


        memset(prgbtmp , 0 , itmp); // itmp = iLBytes*iHeight;


        int temp_start_row = 0;
        int iWidth_1 = width - 1;
        unsigned char* pdst = NULL;
        unsigned char* psrc = NULL;


        // 每行
        for(int i = 0; i < height; i++)
        {
            pdst  = prgbtmp + temp_start_row;
            psrc  = rgb + temp_start_row;
            // 每列
            for(int j = 0; j < width; j++)
            {
                memcpy((pdst  + 3*(iWidth_1 -j)) , (psrc + 3*j)  , 3);
            }
            temp_start_row += iLBytes; // 改乘法运算为加法
        }


        memcpy(rgb , prgbtmp , itmp); // itmp = iLBytes*iHeight;


        flag = true;


    }while(false);


    if(NULL != prgbtmp){
        free(prgbtmp);
    }




    return flag;






}




//RGB24 to BGR24
void TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB24_TO_BGR24(unsigned char *rgb24,unsigned int width,unsigned int height)
{
    if((NULL != rgb24)&&(width > 0)&&(height > 0)) {
        for (int i = 0; i < height; i++) {
            for (int j = 0; j < width; j++) {
                char temp2;
                temp2 = rgb24[(i * width + j) * 3 + 2];
                rgb24[(i * width + j) * 3 + 2] = rgb24[(i * width + j) * 3 + 0];
                rgb24[(i * width + j) * 3 + 0] = temp2;
            }
        }
    }


}






unsigned char TSDL_IMAGE_MERGE_TOOLS::CONVERT_ADJUST(double tmp)
{
    return (unsigned char)((tmp >= 0 && tmp <= 255)?tmp:(tmp < 0 ? 0 : 255));
}




//YUV420P to RGB24
void TSDL_IMAGE_MERGE_TOOLS::CONVERT_YUV420P_TO_RGB24(unsigned char *yuvbuf,unsigned char *rgbbuf,unsigned int width,unsigned int height)
{


    unsigned char *tmpbuf = NULL;
    do
    {
        if((NULL == yuvbuf)||(NULL == rgbbuf)||(0 == width)||(0 == height)){
            break;
        }
        tmpbuf=(unsigned char *)malloc(width*height*3);
        if(NULL == tmpbuf){
            break;
        }
        unsigned char Y,U,V,R,G,B;
        unsigned char* y_planar,*u_planar,*v_planar;
        int rgb_width , u_width;
        rgb_width = width * 3;
        u_width = (width >> 1);
        int ypSize = width * height;
        int upSize = (ypSize>>2);
        int offSet = 0;




        y_planar = yuvbuf;
        u_planar = yuvbuf   + ypSize;
        v_planar = u_planar + upSize;




        for(int i = 0; i < height; i++)
        {
            for(int j = 0; j < width; j ++)
            {
                // Get the Y value from the y planar
                Y = *(y_planar + width * i + j);
                // Get the V value from the u planar
                offSet = (i>>1) * (u_width) + (j>>1);
                V = *(u_planar + offSet);
                // Get the U value from the v planar
                U = *(v_planar + offSet);


                // Cacular the R,G,B values
                // Method 1
                R = TSDL_IMAGE_MERGE_TOOLS::CONVERT_ADJUST((Y + (1.4075 * (V - 128))));
                G = TSDL_IMAGE_MERGE_TOOLS::CONVERT_ADJUST((Y - (0.3455 * (U - 128) - 0.7169 * (V - 128))));
                B = TSDL_IMAGE_MERGE_TOOLS::CONVERT_ADJUST((Y + (1.7790 * (U - 128))));
                /*
                // The following formulas are from MicroSoft' MSDN
                int C,D,E;
                // Method 2
                C = Y - 16;
                D = U - 128;
                E = V - 128;
                R = CONVERT_ADJUST(( 298 * C + 409 * E + 128) >> 8);
                G = CONVERT_ADJUST(( 298 * C - 100 * D - 208 * E + 128) >> 8);
                B = CONVERT_ADJUST(( 298 * C + 516 * D + 128) >> 8);
                R = ((R - 128) * .6 + 128 )>255?255:(R - 128) * .6 + 128;
                G = ((G - 128) * .6 + 128 )>255?255:(G - 128) * .6 + 128;
                B = ((B - 128) * .6 + 128 )>255?255:(B - 128) * .6 + 128;
                */


                offSet = rgb_width * i + j * 3;


                rgbbuf[offSet] = B;
                rgbbuf[offSet + 1] = G;
                rgbbuf[offSet + 2] = R;


            }
        }


    }while (false);


    if(NULL != tmpbuf){
        free(tmpbuf);
        tmpbuf = NULL;
    }






}










void  TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB24_TO_YUV420P(unsigned char *rgbbuf, unsigned char *yuvbuf, unsigned int width, unsigned int height/*, unsigned long *len*/)
{


    if((NULL == yuvbuf)||(NULL == rgbbuf)||(0 == width)||(0 == height)){
        return;
    }


    unsigned char *bufY;
    unsigned char *bufU;
    unsigned char *bufV;
    unsigned char *bufRGB;
    long len = width * height+(width * height)/2;
    memset(yuvbuf,0,len);
    bufY = yuvbuf;
    bufV = yuvbuf + width * height;
    bufU = bufV + (width * height/4);
    //*len = 0;
    unsigned char y, u, v, r, g, b;// , testu , testv;
    unsigned int ylen = width * height;
    unsigned int ulen = (width * height)/4;
    unsigned int vlen = (width * height)/4;
    for (unsigned int j = 0; j     {
        bufRGB = rgbbuf + width * (height - 1 - j) * 3 ;
        for (unsigned int i = 0; i         {
            int pos = width * i + j;
            r = *(bufRGB++);
            g = *(bufRGB++);
            b = *(bufRGB++);
            y = (unsigned char)( ( 66 * r + 129 * g +  25 * b + 128) >> 8) + 16  ;
            u = (unsigned char)( ( -38 * r -  74 * g + 112 * b + 128) >> 8) + 128 ;
            v = (unsigned char)( ( 112 * r -  94 * g -  18 * b + 128) >> 8) + 128 ;
            *(bufY++) = std::fmax( 0, std::fmin(y, 255 ));
            if (j%2==0&&i%2 ==0)
            {
                if (u>255)
                {
                    u=255;
                }
                if (u<0)
                {
                    u = 0;
                }
                *(bufU++) =u;
                //存u分量
            }
            else
            {
                //存v分量
                if (i%2==0)
                {
                    if (v>255)
                    {
                        v = 255;
                    }
                    if (v<0)
                    {
                        v = 0;
                    }
                    *(bufV++) =v;
                }
            }
        }
    }


    //*len = width * height+(width * height)/2;










}






void TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGBA32_MERGE_IMAGE(
        unsigned char *rgb_dst,
        unsigned int width_dst,
        unsigned int height_dst,
        unsigned char *rgb_src,
        unsigned int width_src,
        unsigned int height_src,
        unsigned int lx,
        unsigned int ly,
        unsigned int bpp,
        unsigned int alpha
)
{
    if(ly > height_dst){
        return;
    }
    if(lx > width_dst){
        return;
    }


    unsigned  int begline = ly;
    unsigned  int endline = ly + height_src;
    if((ly + height_src) > height_dst){
        endline = height_dst ;
    }


    unsigned  int cpwidth = width_src;
    if((lx + width_src) > width_dst){
        cpwidth = width_dst - lx;
    }


    unsigned int depth = 3;
    if(32 == bpp){
        depth = 4;
    }


    for(unsigned  int i = begline;i< endline;i++){
        /*RGB颜色透明公式
        Alpha=0--100
        R=(R1*(100-Alpha)+R2*Alpha)/100
        G=(G1*(100-Alpha)+G2*Alpha)/100
        B=(B1*(100-Alpha)+B2*Alpha)/100
          
        示例:RGB1   (   232,   54,   13   )  RGB2   (   94,   186,   233   )  Alpha   =   30       
        R   =   (   232   *   70   +   94   *   30   )   /   100   =   190.6   ->   190       
        G   =   (   54   *   70   +   186   *   30   )   /   100   =   93.6   ->   93       
        B   =   (   13   *   70   +   233   *   30   )   /   100   =   79       
        Alpha   =   50       R   =   (   232   *   50   +   94   *   50   )   /   100   =   163       
        G   =   (   54   *   50   +   186   *   50   )   /   100   =   120       
        B   =   (   13   *   50   +   233   *   50   )   /   100   =   123
        32位色下的颜色混合
        R   =   R1   *   Alpha1   +   R2   *   Alpha2   *   (1-Alpha1)
        G   =   G1   *   Alpha1   +   G2   *   Alpha2   *   (1-Alpha1)
        B   =   B1   *   Alpha1   +   B2   *   Alpha2   *   (1-Alpha1)
        Alpha   =   1   -   (1   -   Alpha1)   *   (   1   -   Alpha2)
        R   =   R   /   Alpha
        G   =   G   /   Alpha
        B   =   B   /   Alpha


        R1、G1、B1、Alpha1指上层的颜色值     R2、G2、B2、Alpha2指下层的颜色值     R、G、B、Alpha指合并后的颜色
        */
        if((0 == alpha)||(alpha > 100)) {
            memcpy(rgb_dst + ((i * width_dst) + lx) * depth, rgb_src + (i * width_src) * depth, cpwidth * depth);
        } else{
            if(24 == bpp){
                unsigned  int len = cpwidth * depth;
                unsigned  int stp = depth;
                for (int j = 0; j < cpwidth * depth; j+stp) {
                    unsigned int R1 = rgb_src[((i * width_src)) * depth + 0];
                    unsigned int G1 = rgb_src[((i * width_src)) * depth + 1];
                    unsigned int B1 = rgb_src[((i * width_src)) * depth + 3];


                    unsigned int R2 = rgb_dst[((i * width_dst) + lx) * depth + 0];
                    unsigned int G2 = rgb_dst[((i * width_dst) + lx) * depth + 1];
                    unsigned int B2 = rgb_dst[((i * width_dst) + lx) * depth + 3];


                    unsigned int R=(R1*(100-alpha)+R2*alpha)/100;
                    unsigned int G=(G1*(100-alpha)+G2*alpha)/100;
                    unsigned int B=(B1*(100-alpha)+B2*alpha)/100;




                    rgb_dst[((i * width_dst) + lx) * depth + 0] = R;
                    rgb_dst[((i * width_dst) + lx) * depth + 1] = G;
                    rgb_dst[((i * width_dst) + lx) * depth + 3] = B;


                }
            }


            if(32 == bpp){
                unsigned  int len = cpwidth * depth;
                unsigned  int stp = depth;
                for (int j = 0; j < cpwidth * depth; j+stp) {
                    unsigned int R1 = rgb_src[((i * width_src)) * depth + 0];
                    unsigned int G1 = rgb_src[((i * width_src)) * depth + 1];
                    unsigned int B1 = rgb_src[((i * width_src)) * depth + 3];
                    unsigned int A1 = rgb_src[((i * width_src)) * depth + 4];


                    unsigned int R2 = rgb_dst[((i * width_dst) + lx) * depth + 0];
                    unsigned int G2 = rgb_dst[((i * width_dst) + lx) * depth + 1];
                    unsigned int B2 = rgb_dst[((i * width_dst) + lx) * depth + 3];
                    unsigned int A2 = rgb_dst[((i * width_dst) + lx) * depth + 4];


                    unsigned int R = R1 * A1 + R2 * A2 * (1-A1);
                    unsigned int G = G1 * A1 + G2 * A2 * (1-A1);
                    unsigned int B = B1 * A1 + B2 * A2 * (1-A1);
                    unsigned int jsalpha = 1-(1-A1) * (1-A2);
                    R = R /jsalpha;
                    G = G /jsalpha;
                    B = B /jsalpha;


                    rgb_dst[((i * width_dst) + lx) * depth + 0] = R;
                    rgb_dst[((i * width_dst) + lx) * depth + 1] = G;
                    rgb_dst[((i * width_dst) + lx) * depth + 3] = B;
                    rgb_dst[((i * width_dst) + lx) * depth + 4] = jsalpha;


                }
            }


        }


    }




}




/*
void TSDL_IMAGE_MERGE_TOOLS::CONVERT_SAVE_RGB_IMAGE(const char *filename, unsigned char *rgb, unsigned int width, unsigned  int height, unsigned int bpp)
{
    typedef struct tagBITMAPFILEHEADER
    {
        unsigned short  bfType;
        unsigned long bfSize;
        unsigned short bfReserved1;
        unsigned short bfReserved2;
        unsigned long bfOffBits;
    } BITMAPFILEHEADER;


    typedef struct tagBITMAPINFOHEADER {
        unsigned long biSize;
        long biWidth;
        long biHeight;
        unsigned short biPlanes;
        unsigned short biBitCount;
        unsigned long biCompression;
        unsigned long biSizeImage;
        long biXPelsPerMeter;
        long biYPelsPerMeter;
        unsigned long biClrUsed;
        unsigned long biClrImportant;
    } BITMAPINFOHEADER;






    BITMAPFILEHEADER bmpheader;
    BITMAPINFOHEADER bmpinfo;
    FILE *fp = NULL;


    do
    {
        if((NULL == rgb)||(0 == width)||(0 == height))
        {
          break;
        }


        fp = fopen(filename, "wb");
        if (NULL == fp) {
            break;
        }


        memset(&bmpheader,0,sizeof(BITMAPFILEHEADER));
        memset(&bmpinfo,0,sizeof(BITMAPINFOHEADER));


        bmpheader.bfType = ('M' << 8) | 'B';
        bmpheader.bfReserved1 = 0;
        bmpheader.bfReserved2 = 0;
        bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
        bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp / 8;


        bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
        bmpinfo.biWidth = width;
        bmpinfo.biHeight = 0 - height;
        bmpinfo.biPlanes = 1;
        bmpinfo.biBitCount = bpp;
        unsigned long BI_RGB = 0;
        bmpinfo.biCompression = BI_RGB;
        bmpinfo.biSizeImage = 0;
        bmpinfo.biXPelsPerMeter = 100;
        bmpinfo.biYPelsPerMeter = 100;
        bmpinfo.biClrUsed = 0;
        bmpinfo.biClrImportant = 0;


        fwrite(&bmpheader, sizeof(BITMAPFILEHEADER), 1, fp);
        fseek(fp,0,SEEK_END);
        fwrite(&bmpinfo, sizeof(BITMAPINFOHEADER), 1, fp);
        fseek(fp,0,SEEK_END);
        fwrite(rgb, width*height*bpp / 8, 1, fp);


    }while(false);


    if(NULL != fp){
        fclose(fp);
        fp = NULL;
    }




}
 */






void TSDL_IMAGE_MERGE_TOOLS::CONVERT_SAVE_RGB_IMAGE(const char *filename, unsigned char *rgb, unsigned int width, unsigned  int height, unsigned int bpp)
{
    typedef long LONG;
    typedef unsigned long DWORD;
    typedef unsigned short WORD;




    typedef struct {
        WORD    bfType;
        DWORD   bfSize;
        WORD    bfReserved1;
        WORD    bfReserved2;
        DWORD   bfOffBits;
    } BMPFILEHEADER_T;


    typedef struct{
        DWORD      biSize;
        LONG       biWidth;
        LONG       biHeight;
        WORD       biPlanes;
        WORD       biBitCount;
        DWORD      biCompression;
        DWORD      biSizeImage;
        LONG       biXPelsPerMeter;
        LONG       biYPelsPerMeter;
        DWORD      biClrUsed;
        DWORD      biClrImportant;
    } BMPINFOHEADER_T;




    FILE *fp = NULL;


    do
    {
        if((NULL == rgb)||(0 == width)||(0 == height))
        {
            break;
        }


        fp = fopen(filename, "wb+");
        if (NULL == fp) {
            break;
        }


        //分别为rgb数据,要保存的bmp文件名,图片长宽
        int size = width*height*bpp/8*sizeof(char); // 每个像素点3个字节
        // 位图第一部分,文件信息
        BMPFILEHEADER_T bfh;
        bfh.bfType = (WORD)0x4d42;  //bm
        bfh.bfSize = size  // data size
                     + sizeof( BMPFILEHEADER_T ) // first section size
                     + sizeof( BMPINFOHEADER_T ) // second section size
                ;
        bfh.bfReserved1 = 0; // reserved
        bfh.bfReserved2 = 0; // reserved
        bfh.bfOffBits = sizeof( BMPFILEHEADER_T )+ sizeof( BMPINFOHEADER_T );//真正的数据的位置


        // 位图第二部分,数据信息
        BMPINFOHEADER_T bih;
        bih.biSize = sizeof(BMPINFOHEADER_T);
        bih.biWidth = width;
        bih.biHeight = height;//BMP图片从最后一个点开始扫描,显示时图片是倒着的,所以用-height,这样图片就正了
        bih.biPlanes = 1;//为1,不用改


        bih.biBitCount = bpp;
        bih.biCompression = 0;//不压缩
        bih.biSizeImage = size;
        bih.biXPelsPerMeter = 0 ;//像素每米
        bih.biYPelsPerMeter = 0 ;
        bih.biClrUsed = 0;//已用过的颜色,24位的为0
        bih.biClrImportant = 0;//每个像素都重要


        //BMPINFOHEADER_T
        fwrite(&bfh,sizeof(BMPFILEHEADER_T),1,fp);
        fwrite(&bih,sizeof(BMPINFOHEADER_T),1,fp);
        fwrite(rgb,size,1,fp);


        /*
        fwrite( &bfh, 8, 1,  fp );//由于linux上4字节对齐,而信息头大小为54字节,第一部分14字节,第二部分40字节,所以会将第一部分补齐为16自己,直接用sizeof,打开图片时就会遇到premature end-of-file encountered错误
        //fseek(fp,0,SEEK_END);
        fwrite(&bfh.bfReserved2, sizeof(bfh.bfReserved2), 1, fp);
        //fseek(fp,0,SEEK_END);
        fwrite(&bfh.bfOffBits, sizeof(bfh.bfOffBits), 1, fp);
        //fseek(fp,0,SEEK_END);
        fwrite(&bih, sizeof(BMPINFOHEADER_T),1,fp );
        //fseek(fp,0,SEEK_END);
        fwrite(rgb,size,1,fp);
         */




    }while(false);


    if(NULL != fp){
        fclose(fp);
        fp = NULL;
    }




}
















class TSDL_SURFACE_IMAGE{
public:
    TSDL_SURFACE_IMAGE()
    {
        this->SDL_Surface_Init();
    }
    virtual ~TSDL_SURFACE_IMAGE()
    {
       this->SDL_Surface_Free();
    }
public:
    SDL_Surface *Get_SDL_Surface()
    {
        return this->FSDL_Surface_src;
    }


    int SDL_Surface_Save_PNG(const char *file)
    {
        int flag = -1;
        do
        {
            if((0 != this->FSDL_Status_code)||(NULL == this->FSDL_Surface_src)) {
                break;
            }
            flag = IMG_SavePNG(this->FSDL_Surface_src,file);\


        }while (false);




        if(0 != flag){
            SDL_Log("%s","SDL_Surface_Save_PNG error\n");
        }


        return flag ;


    }


    int SDL_Surface_Save_BMP(const char *file)
    {
        int flag = -1;
        do
        {
            if((0 != this->FSDL_Status_code)||(NULL == this->FSDL_Surface_src)) {
                break;
            }
            flag = SDL_SaveBMP(this->FSDL_Surface_src,file);




        }while (false);




        if(0 != flag){
            SDL_Log("%s","SDL_Surface_Save_BMP error\n");
        }


        return flag ;




    }




    int SDL_Merge_Image_To( int x, int y, TSDL_SURFACE_IMAGE *dst)
    {
        int flag = this->SDL_Merge_Image(x, y, this, dst);
        if(0 != flag){
            SDL_Log("%s","SDL_Merge_Image_To error\n");
        }


        return flag;


    }


    int SDL_Merge_Image_From( int x, int y, TSDL_SURFACE_IMAGE *src)
    {
        int flag = this->SDL_Merge_Image(x, y, src, this);
        if(0 != flag){
            SDL_Log("%s","SDL_Merge_Image_From error\n");
        }


        return flag;


    }


    int SDL_Merge_Image_From_Scaled(int x, int y,int w,int h, TSDL_SURFACE_IMAGE *src)
    {
        int flag = this->SDL_Merge_Image_Scaled(x, y,w,h, src, this);
        if(0 != flag){
            SDL_Log("%s","SDL_Merge_Image_From error\n");
        }


        return flag;




    }




    unsigned  char *get_yuv_frame()
    {


        unsigned char *rgb = NULL;
        do
        {
            if(NULL == this->FSDL_Surface_src){
               break;
            }


            if(NULL == this->FYUV_Data){
               delete[] this->FYUV_Data ;
               this->FYUV_Data = NULL;
            }


            unsigned  int width = this->FSDL_Surface_width;
            unsigned  int height= this->FSDL_Surface_height;
            unsigned  int NSize = width*height*24/8;
            this->FYUV_Data     = new unsigned char[NSize/2];
            if(NULL == this->FYUV_Data){
                break;
            }


            rgb = new unsigned char[NSize];
            if(NULL == rgb){
                break;
            }


            unsigned  char *ppixels = (unsigned char *)this->FSDL_Surface_src->pixels;
            memcpy(rgb,ppixels,NSize);
            TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB24_TO_BGR24(rgb,width,height);
            TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB_MIRRORR(rgb,width,height,24,false);
            TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB24_TO_YUV420P(rgb,this->FYUV_Data,width,height);




        }while(false);


        if(NULL != rgb){
            delete[] rgb;
            rgb = NULL;
        }




        return  this->FYUV_Data;




    }




    unsigned  char *get_rgb_data()
    {
        do
        {
            if(NULL == this->FSDL_Surface_src){
                break;
            }


            if(NULL == this->FRGB_Data){
                delete[] this->FRGB_Data ;
                this->FRGB_Data = NULL;
            }


            unsigned  int width = this->FSDL_Surface_width;
            unsigned  int height= this->FSDL_Surface_height;
            unsigned  int NSize = width*height*24/8;
            this->FRGB_Data     = new unsigned char[NSize];
            if(NULL == this->FRGB_Data){
                break;
            }


            unsigned  char *ppixels = (unsigned char *)this->FSDL_Surface_src->pixels;
            memcpy(this->FRGB_Data,ppixels,NSize);
            TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB24_TO_BGR24(this->FRGB_Data,width,height);


        }while(false);




        return  this->FRGB_Data;






    }




    unsigned  char *get_rgb_frame()
    {
        this->FSDL_Surface_src->pixels ;


    }




public:
    unsigned  int Get_Surface_width()
    {
        return this->FSDL_Surface_width;
    }


    unsigned  int Get_Surface_height()
    {
        return  this->FSDL_Surface_height;
    }


protected:
    int SDL_Merge_Image( int x, int y, TSDL_SURFACE_IMAGE *src, TSDL_SURFACE_IMAGE *dst)
    {
        int flag = -1;
        do
        {
            if((NULL == src)||(NULL == dst)||(src == dst)||(0 != this->FSDL_Status_code)){
                break;
            }


            flag = this->SDL_Surface_Merge(x, y, src->Get_SDL_Surface(), dst->Get_SDL_Surface());


        }while (false);




        return flag ;


    }


    int SDL_Surface_Merge( int x, int y, SDL_Surface *src, SDL_Surface *dst)
    {
        int flag = -1;
        do
        {
            if((NULL == src)||(NULL == dst)||(src == dst)){
                break;
            }


            SDL_Rect offset;
            offset.x = x;
            offset.y = y;
            flag = SDL_BlitSurface(src, NULL, dst, &offset);


        }while(false);


        return  flag;


    }


    int SDL_Merge_Image_Scaled( int x, int y,int w,int h, TSDL_SURFACE_IMAGE *src, TSDL_SURFACE_IMAGE *dst)
    {
        int flag = -1;
        do
        {
            if((NULL == src)||(NULL == dst)||(src == dst)||(0 != this->FSDL_Status_code)){
                break;
            }


            flag = this->SDL_Surface_Merge_Scaled(x, y,w,h, src->Get_SDL_Surface(), dst->Get_SDL_Surface());


        }while (false);




        return flag ;


    }


    int SDL_Surface_Merge_Scaled( int x, int y, int w,int h,SDL_Surface *src, SDL_Surface *dst)
    {
        int flag = -1;
        do
        {
            if((NULL == src)||(NULL == dst)||(src == dst)){
                break;
            }


            SDL_Rect offset;
            offset.x = x;
            offset.y = y;
            offset.w = w;
            offset.h = h;


            //flag = SDL_SoftStretch(src, NULL,dst,&offset);
            //flag = SDL_LowerBlitScaled(src, NULL,dst,&offset);
            flag = SDL_UpperBlitScaled(src, NULL,dst,&offset);
            //flag = SDL_BlitSurface(src, NULL, dst, &offset);


        }while(false);


        return  flag;


    }






    int  SDL_Surface_Init()
    {
        this->FYUV_Data = NULL;
        this->FRGB_Data = NULL;
        this->FSDL_Surface_height = 0;
        this->FSDL_Surface_width  = 0;
        if((this->FSDL_Status_code  = SDL_WasInit(SDL_INIT_EVERYTHING)) < 0){
            this->FSDL_Status_code  = SDL_Init(SDL_INIT_EVERYTHING);
        }


        return  this->FSDL_Status_code;


    }


    void SDL_Surface_Free()
    {
        if(NULL != this->FYUV_Data){
            delete this->FYUV_Data;
            this->FYUV_Data = NULL;
        }
        if(NULL != this->FRGB_Data){
            delete [] this->FRGB_Data;
            this->FRGB_Data = NULL;
        }
        if(NULL != this->FSDL_Surface_src){
            SDL_FreeSurface(this->FSDL_Surface_src);
            this->FSDL_Surface_src = NULL;
        }


        SDL_Quit();
    }






protected:
    SDL_Surface *FSDL_Surface_src;
    int          FSDL_Status_code;
protected:
    unsigned  int FSDL_Surface_width;
    unsigned  int FSDL_Surface_height;
protected:
    unsigned char *FYUV_Data;
    unsigned char *FRGB_Data;
protected:








};










class TSDL_SURFACE_IMAGE_FOR_RGB_CUSTOM :public TSDL_SURFACE_IMAGE{
public:
    TSDL_SURFACE_IMAGE_FOR_RGB_CUSTOM(unsigned int width = 1280, unsigned int height = 1080,SDL_Color color={255,255,255,255},unsigned int alpha = 255)
    {
        do
        {
            this->FSDL_Surface_width  = width ;
            this->FSDL_Surface_height = height;


            #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                Uint32 rmask = 0xff000000;
                Uint32 gmask = 0x00ff0000;
                Uint32 bmask = 0x0000ff00;
                Uint32 amask = 0x000000ff;
            #else
                Uint32 rmask = 0x000000ff;
                Uint32 gmask = 0x0000ff00;
                Uint32 bmask = 0x00ff0000;
                Uint32 amask = 0xff000000;
            #endif


            //for test ,default is SDL_PIXELFORMAT_ABGR8888
            int bpp = bpp;
            //for test ,default is SDL_PIXELFORMAT_ABGR8888
            SDL_bool flag = SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGB24,&bpp,&rmask,&gmask,&bmask,&amask);
            this->FSDL_Surface_src = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,bpp,rmask,gmask,bmask,amask);
            if(NULL == this->FSDL_Surface_src){
                this->FSDL_Surface_src = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,bpp,0,0,0,0);
            }


            //default SDL_PIXELFORMAT_RGB24
            if(SDL_PIXELFORMAT_RGB24 != this->FSDL_Surface_src->format->format){
                SDL_Surface *newsurface = SDL_ConvertSurfaceFormat(this->FSDL_Surface_src,SDL_PIXELFORMAT_RGB24, 0);
                if(NULL != newsurface){
                    SDL_FreeSurface(this->FSDL_Surface_src);
                    this->FSDL_Surface_src = newsurface;
                }
            }


            this->FSDL_Surface_src = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,bpp,rmask,gmask,bmask,amask);
            if(NULL == this->FSDL_Surface_src){
                this->FSDL_Surface_src = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,bpp,0,0,0,0);
            }




            //set alpha bend mod ,the default mode and functiong is SDL_BLENDMODE_BLEND
            SDL_BlendMode blendMode;
            SDL_GetSurfaceBlendMode(this->FSDL_Surface_src,&blendMode);
            if(SDL_BLENDMODE_BLEND != blendMode){
                SDL_SetSurfaceBlendMode(this->FSDL_Surface_src, SDL_BLENDMODE_BLEND);
            }


            Uint32 colorKey = SDL_MapRGBA(this->FSDL_Surface_src->format, color.r,color.g,color.b,color.a);
            SDL_FillRect(this->FSDL_Surface_src,NULL,colorKey);


            /*
            unsigned int  step  = bpp / 8;
            unsigned int  NSize = width * height * step;
            unsigned char *ppixels = (unsigned char *)this->FSDL_Surface_src->pixels;
            for (unsigned int i = 0; i < NSize; i = i+step) {
                ppixels[i+0] = color.r;
                ppixels[i+1] = color.g;
                ppixels[i+2] = color.b;
            }
             */


            SDL_SetSurfaceAlphaMod(this->FSDL_Surface_src,alpha);
            SDL_SetClipRect(this->FSDL_Surface_src,NULL);
            SDL_BlitSurface(this->FSDL_Surface_src,NULL,this->FSDL_Surface_src,NULL);




        }while(false);






    }


    virtual ~TSDL_SURFACE_IMAGE_FOR_RGB_CUSTOM(){}


public:


protected:






};








class TSDL_SURFACE_IMAGE_FOR_RGB_MEM :public TSDL_SURFACE_IMAGE{
public:
    TSDL_SURFACE_IMAGE_FOR_RGB_MEM(void *pixels,unsigned int width = 1280, unsigned int height = 1080, unsigned int alpha = 255)
    {
        do
        {
            if(NULL == pixels){
                break;
            }


            this->FSDL_Surface_width  = width ;
            this->FSDL_Surface_height = height;


            #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                Uint32 rmask = 0xff000000;
                Uint32 gmask = 0x00ff0000;
                Uint32 bmask = 0x0000ff00;
                Uint32 amask = 0x000000ff;
            #else
                Uint32 rmask = 0x000000ff;
                Uint32 gmask = 0x0000ff00;
                Uint32 bmask = 0x00ff0000;
                Uint32 amask = 0xff000000;
            #endif


            int bpp = 24;
            //for test ,default is SDL_PIXELFORMAT_ABGR8888
            SDL_bool flag = SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGB24,&bpp,&rmask,&gmask,&bmask,&amask);
            this->FSDL_Surface_src = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,bpp,rmask,gmask,bmask,amask);
            //default SDL_PIXELFORMAT_RGB24
            if(SDL_PIXELFORMAT_RGB24 != this->FSDL_Surface_src->format->format){
                SDL_Surface *newsurface = SDL_ConvertSurfaceFormat(this->FSDL_Surface_src,SDL_PIXELFORMAT_RGB24, 0);
                if(NULL != newsurface){
                    SDL_FreeSurface(this->FSDL_Surface_src);
                    this->FSDL_Surface_src = newsurface;
                }
            }


            //set alpha bend mode ,the default mode and functiong is SDL_BLENDMODE_BLEND
            SDL_BlendMode blendMode;
            SDL_GetSurfaceBlendMode(this->FSDL_Surface_src,&blendMode);
            if(SDL_BLENDMODE_BLEND != blendMode){
                SDL_SetSurfaceBlendMode(this->FSDL_Surface_src, SDL_BLENDMODE_BLEND);
            }


            unsigned  int size = width*height*bpp /8 ;
            memcpy(this->FSDL_Surface_src->pixels,pixels,size);
            SDL_SetClipRect(this->FSDL_Surface_src,NULL);


            SDL_SetSurfaceAlphaMod(this->FSDL_Surface_src,alpha);
            SDL_SetClipRect(this->FSDL_Surface_src,NULL);
            SDL_BlitSurface(this->FSDL_Surface_src,NULL,this->FSDL_Surface_src,NULL);


        }while(false);




    }


    virtual ~TSDL_SURFACE_IMAGE_FOR_RGB_MEM() { }
public:


protected:






};










/*
class TSDL_SURFACE_IMAGE_FOR_YUV420P_MEM :public TSDL_SURFACE_IMAGE{
public:
    TSDL_SURFACE_IMAGE_FOR_YUV420P_MEM(void *pixels,unsigned int width = 1280, unsigned int height = 1080,unsigned int alpha = 255)
    {
        unsigned  char *rgb24 = NULL;
        do
        {
            if(NULL == pixels){
                break;
            }


            this->FSDL_Surface_width  = width ;
            this->FSDL_Surface_height = height;


            #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                Uint32 rmask = 0xff000000;
                Uint32 gmask = 0x00ff0000;
                Uint32 bmask = 0x0000ff00;
                Uint32 amask = 0x000000ff;
            #else
                Uint32 rmask = 0x000000ff;
                Uint32 gmask = 0x0000ff00;
                Uint32 bmask = 0x00ff0000;
                Uint32 amask = 0xff000000;
            #endif


            int bpp = 24;
            //for test ,default is SDL_PIXELFORMAT_ABGR8888
            SDL_bool flag = SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGB24,&bpp,&rmask,&gmask,&bmask,&amask);
            this->FSDL_Surface_src = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,bpp,rmask,gmask,bmask,amask);
            if(SDL_PIXELFORMAT_RGB24 != this->FSDL_Surface_src->format->format){
                SDL_Surface *newsurface = SDL_ConvertSurfaceFormat(this->FSDL_Surface_src,SDL_PIXELFORMAT_RGB24, 0);
                if(NULL != newsurface){
                    SDL_FreeSurface(this->FSDL_Surface_src);
                    this->FSDL_Surface_src = newsurface;
                }
            }


            //set alpha bend mod ,the default mode and functiong is SDL_BLENDMODE_BLEND
            SDL_BlendMode blendMode;
            SDL_GetSurfaceBlendMode(this->FSDL_Surface_src,&blendMode);
            if(SDL_BLENDMODE_BLEND != blendMode){
                SDL_SetSurfaceBlendMode(this->FSDL_Surface_src, SDL_BLENDMODE_BLEND);
            }


            unsigned  int Nrgb24size = this->FSDL_Surface_width*this->FSDL_Surface_height*3;
            rgb24 = new unsigned char[Nrgb24size];
            if(NULL == rgb24){
                break;
            }


            memset(rgb24,0,Nrgb24size);


            TSDL_IMAGE_MERGE_TOOLS::
            CONVERT_YUV420P_TO_RGB24((unsigned char*)pixels,rgb24,this->FSDL_Surface_width,this->FSDL_Surface_height);
            TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB24_TO_BGR24(rgb24,width,height);
            TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB_MIRRORR(rgb24,width, height,24,false);
            memcpy(this->FSDL_Surface_src->pixels,rgb24,Nrgb24size);
            SDL_SetSurfaceAlphaMod(this->FSDL_Surface_src,alpha);
            SDL_SetClipRect(this->FSDL_Surface_src,NULL);
            SDL_BlitSurface(this->FSDL_Surface_src,NULL,this->FSDL_Surface_src,NULL);


        }while(false);


        if(NULL != rgb24){
            delete [] rgb24;
        }


    }




    virtual ~TSDL_SURFACE_IMAGE_FOR_YUV420P_MEM(){}


public:


protected:






};
*/




class TSDL_SURFACE_IMAGE_FOR_YUV420P_MEM :public TSDL_SURFACE_IMAGE{
public:
    TSDL_SURFACE_IMAGE_FOR_YUV420P_MEM(void *pixels,unsigned int width = 1280, unsigned int height = 1080,unsigned int alpha = 255)
    {
        unsigned  char *rgb24 = NULL;
        do
        {
            if(NULL == pixels){
                break;
            }


            this->FSDL_Surface_width  = width ;
            this->FSDL_Surface_height = height;


            #if SDL_BYTEORDER == SDL_BIG_ENDIAN
            Uint32 rmask = 0xff000000;
            Uint32 gmask = 0x00ff0000;
            Uint32 bmask = 0x0000ff00;
            Uint32 amask = 0x000000ff;
            #else
            Uint32 rmask = 0x000000ff;
            Uint32 gmask = 0x0000ff00;
            Uint32 bmask = 0x00ff0000;
            Uint32 amask = 0xff000000;
            #endif


            int bpp = 24;
            //for test ,default is SDL_PIXELFORMAT_ABGR8888
            SDL_bool flag = SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGB24,&bpp,&rmask,&gmask,&bmask,&amask);
            this->FSDL_Surface_src = SDL_CreateRGBSurface(SDL_SWSURFACE,width,height,bpp,rmask,gmask,bmask,amask);
            if(SDL_PIXELFORMAT_RGB24 != this->FSDL_Surface_src->format->format){
                SDL_Surface *newsurface = SDL_ConvertSurfaceFormat(this->FSDL_Surface_src,SDL_PIXELFORMAT_RGB24, 0);
                if(NULL != newsurface){
                    SDL_FreeSurface(this->FSDL_Surface_src);
                    this->FSDL_Surface_src = newsurface;
                }
            }


            //set alpha bend mod ,the default mode and functiong is SDL_BLENDMODE_BLEND
            SDL_BlendMode blendMode;
            SDL_GetSurfaceBlendMode(this->FSDL_Surface_src,&blendMode);
            if(SDL_BLENDMODE_BLEND != blendMode){
                SDL_SetSurfaceBlendMode(this->FSDL_Surface_src, SDL_BLENDMODE_BLEND);
            }


            unsigned  int Nrgb24size = this->FSDL_Surface_width*this->FSDL_Surface_height*3;
            rgb24 = new unsigned char[Nrgb24size];
            if(NULL == rgb24){
                break;
            }
            memset(rgb24,0,Nrgb24size);
            TSDL_IMAGE_MERGE_TOOLS::CONVERT_YUV420P_TO_RGB24((unsigned char*)pixels,rgb24,width,height);
            //TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB24_TO_BGR24(rgb24,width,height);
            //TSDL_IMAGE_MERGE_TOOLS::CONVERT_RGB_MIRRORR(rgb24,width, height,24,false);


            memcpy(this->FSDL_Surface_src->pixels,rgb24,Nrgb24size);


            SDL_SetSurfaceAlphaMod(this->FSDL_Surface_src,alpha);
            SDL_SetClipRect(this->FSDL_Surface_src,NULL);
            SDL_BlitSurface(this->FSDL_Surface_src,NULL,this->FSDL_Surface_src,NULL);


        }while(false);


        if(NULL != rgb24){
            delete [] rgb24;
        }


    }




    virtual ~TSDL_SURFACE_IMAGE_FOR_YUV420P_MEM(){}


public:


protected:






};






class TSDL_SURFACE_IMAGE_FOR_FILE :public TSDL_SURFACE_IMAGE{
public:
    TSDL_SURFACE_IMAGE_FOR_FILE(const char *filename,unsigned int alpha = 255)
    {
        this->FSDL_Status_code = IMG_Init(0/*SDL_INIT_EVERYTHING*/);
        if(this->FSDL_Status_code > -1){
            this->FSDL_Surface_src = IMG_Load(filename);
            if(NULL != this->FSDL_Surface_src){
                //default SDL_PIXELFORMAT_RGB24
                if(SDL_PIXELFORMAT_RGB24 != this->FSDL_Surface_src->format->format){
                    SDL_Surface *newsurface = SDL_ConvertSurfaceFormat(this->FSDL_Surface_src,SDL_PIXELFORMAT_RGB24, 0);
                    if(NULL != newsurface){
                        SDL_FreeSurface(this->FSDL_Surface_src);
                        this->FSDL_Surface_src = newsurface;
                    }
                }


                //set alpha bend mod ,the default mode and functiong is SDL_BLENDMODE_BLEND
                SDL_BlendMode blendMode;
                SDL_GetSurfaceBlendMode(this->FSDL_Surface_src,&blendMode);
                if(SDL_BLENDMODE_BLEND != blendMode){
                    SDL_SetSurfaceBlendMode(this->FSDL_Surface_src, SDL_BLENDMODE_BLEND);
                }


                this->FSDL_Surface_width  = this->FSDL_Surface_src->w ;
                this->FSDL_Surface_height = this->FSDL_Surface_src->h ;
                SDL_SetSurfaceAlphaMod(this->FSDL_Surface_src,alpha);
                SDL_SetClipRect(this->FSDL_Surface_src,NULL);
                SDL_BlitSurface(this->FSDL_Surface_src,NULL,this->FSDL_Surface_src,NULL);


            }
        }
    }
    virtual ~TSDL_SURFACE_IMAGE_FOR_FILE()
    {
        IMG_Quit();
    }


public:


protected:






};




class TSDL_SURFACE_IMAGE_FOR_TTF :public TSDL_SURFACE_IMAGE{
public:




public:
    TSDL_SURFACE_IMAGE_FOR_TTF(const char *fontfile,const char *text, TColor fgcolor={0,0,0,0},TColor bgcolor={100,100,100,0},unsigned int fontsize = 20,TFontStyle fontstyle = TFontStyle::STYLE_TTF_NORMAL,TRenderType rendertype = TRenderType::TYPE_SOLID,unsigned int alpha = 255 )
    {
        this->FSDL_Status_code = TTF_Init();
        if(this->FSDL_Status_code > -1){
            this->FSDL_Surface_Font = TTF_OpenFont(fontfile,fontsize);
            if(NULL != this->FSDL_Surface_Font){
                SDL_Color fg = {0,0,0,0};
                SDL_Color bg = {255,0,0,0};
                memcpy(&fg,&fgcolor,sizeof(SDL_Color));
                memcpy(&bg,&bgcolor,sizeof(SDL_Color));
                TTF_SetFontStyle(this->FSDL_Surface_Font,fontstyle);
                if(TRenderType::TYPE_SHADED == rendertype){
                    this->FSDL_Surface_src = TTF_RenderUTF8_Shaded(this->FSDL_Surface_Font,text,fg,bg);
                } else if(TRenderType::TYPE_BLENDED == rendertype){
                    this->FSDL_Surface_src = TTF_RenderUTF8_Blended(this->FSDL_Surface_Font,text,fg);
                }else{
                    this->FSDL_Surface_src = TTF_RenderUTF8_Solid(this->FSDL_Surface_Font,text,fg);
                }


                if(NULL != this->FSDL_Surface_src){
                    this->FSDL_Surface_width  = this->FSDL_Surface_src->w ;
                    this->FSDL_Surface_height = this->FSDL_Surface_src->h ;


                    //default SDL_PIXELFORMAT_RGB24
                    if(SDL_PIXELFORMAT_RGB24 != this->FSDL_Surface_src->format->format){
                        SDL_Surface *newsurface = SDL_ConvertSurfaceFormat(this->FSDL_Surface_src,SDL_PIXELFORMAT_RGB24, 0);
                        if(NULL != newsurface){
                            SDL_FreeSurface(this->FSDL_Surface_src);
                            this->FSDL_Surface_src = newsurface;
                        }
                    }


                    //set alpha bend mod ,the default mode and functiong is SDL_BLENDMODE_BLEND
                    SDL_BlendMode blendMode;
                    SDL_GetSurfaceBlendMode(this->FSDL_Surface_src,&blendMode);
                    if(SDL_BLENDMODE_BLEND != blendMode){
                        SDL_SetSurfaceBlendMode(this->FSDL_Surface_src, SDL_BLENDMODE_BLEND);
                    }


                    SDL_SetSurfaceAlphaMod(this->FSDL_Surface_src,alpha);
                    SDL_SetClipRect(this->FSDL_Surface_src,NULL);
                    SDL_BlitSurface(this->FSDL_Surface_src,NULL,this->FSDL_Surface_src,NULL);


                }
            }
        }


    }
    virtual ~TSDL_SURFACE_IMAGE_FOR_TTF()
    {
        if(NULL != this->FSDL_Surface_Font){
            TTF_CloseFont(this->FSDL_Surface_Font);
            this->FSDL_Surface_Font = NULL;
        }
        TTF_Quit();
    }


public:


protected:
    TTF_Font *FSDL_Surface_Font;


protected:






};








TXImage::TXImage()
{
    this->frgbframe= NULL;
    this->fyuvframe= NULL;
    this->fimage   = NULL;
    this->fwidth   = 0;
    this->fheight  = 0;
}




TXImage::~TXImage()
{
    if(NULL != this->fimage){
        delete this->fimage;
    }
    if(NULL != this->frgbframe){
        delete[] this->frgbframe;
    }
    if(NULL != this->fyuvframe){
        delete[] this->fyuvframe;
    }


}




int TXImage::saveimagepng(const char *file)
{
    return  this->fimage->SDL_Surface_Save_PNG(file);


}




int TXImage::saveimagebmp(const char *file)
{
    return  this->fimage->SDL_Surface_Save_BMP(file);


}




int TXImage::mergeimage(int x,int y,TXImage *src)
{
    return this->fimage->SDL_Merge_Image_From(x,y,src->getimage());


}




int TXImage::mergeimageScaled(int x,int y,int w,int h,TXImage *src)
{
    return this->fimage->SDL_Merge_Image_From_Scaled(x,y,w,h,src->getimage());
}


unsigned  int TXImage::getwidth()
{
    return (this->fwidth = this->fimage->Get_Surface_width());
}




unsigned  int TXImage::getheight()
{
    return (this->fheight = this->fimage->Get_Surface_height());
}




TSDL_SURFACE_IMAGE *TXImage::getimage()
{
    return  this->fimage;
}






unsigned  char *TXImage::getyuvframe()
{
    return this->fimage->get_yuv_frame();
}


unsigned  char *TXImage::getrgbframe()
{
    return this->fimage->get_rgb_frame();
}




unsigned  char *TXImage::getrgbdata()
{
    return this->fimage->get_rgb_data();
}




TXrgbimage::TXrgbimage(unsigned int width,unsigned int height,TColor color,unsigned int alpha)
{
    SDL_Color tmpcolor;
    tmpcolor.r = color.r;
    tmpcolor.g = color.g;
    tmpcolor.b = color.b;
    tmpcolor.a = color.a;
    this->fimage = new TSDL_SURFACE_IMAGE_FOR_RGB_CUSTOM(width,height,tmpcolor,alpha);
}
TXrgbimage::~TXrgbimage() {}








TXrgbmemimage::TXrgbmemimage(void *pixels,unsigned int width , unsigned int height,unsigned int alpha)
{
    this->fimage = new TSDL_SURFACE_IMAGE_FOR_RGB_MEM(pixels,width,height,alpha);
}
TXrgbmemimage::~TXrgbmemimage() {}








TXyuvmemimage::TXyuvmemimage(void *pixels,unsigned int width, unsigned int height,unsigned int alpha)
{
    this->fimage = new TSDL_SURFACE_IMAGE_FOR_YUV420P_MEM(pixels,width,height,alpha);
}
TXyuvmemimage::~TXyuvmemimage() { }








TXlocalfileimage::TXlocalfileimage(const char *filename,unsigned int alpha)
{
    this->fimage = new TSDL_SURFACE_IMAGE_FOR_FILE(filename,alpha);
}
TXlocalfileimage::~TXlocalfileimage() { }








TXttfimage::TXttfimage(const char *fontfile, const char *text,TColor fgcolor, TColor bgcolor,unsigned int fontsize ,TFontStyle fontstyle ,TRenderType rendertype,unsigned int alpha)
{
    this->fimage = new TSDL_SURFACE_IMAGE_FOR_TTF(fontfile,text,fgcolor,bgcolor,fontsize,fontstyle,rendertype,alpha);
}
TXttfimage::~TXttfimage() { }



























你可能感兴趣的:(SDL--主题)