我只知道怎么旋转180度,,其他的正在找

解决方案 »

  1.   

    HDIB WINAPI RotateDib( HDIB org, int angle, DWORD fill )
    {
    if( org == NULL ) return NULL; LPSTR lpDib = (LPSTR) ::GlobalLock( (HGLOBAL)org );
    LPSTR lpDib1 = NULL;
    CPoint pt1,pt2;
    LPBITMAPINFO lpDIBHdr = (LPBITMAPINFO)lpDib;
    LPBITMAPINFO lpDIBHdr1 = NULL;
    HDIB ret = NULL;
    int w = (int)DIBWidth( lpDib );
    int h = (int)DIBHeight( lpDib );
    int nBytesPerLine;
    int maxX,maxY,minX,minY,offsetX,offsetY;
    DWORD size;
    int sizeh = sizeof(BITMAPINFOHEADER)
    +sizeof(RGBQUAD)*DIBNumColors(lpDib);
    double SIN_ALPHA;
    double COS_ALPHA;
    int xc[4];
    int yc[4]; if( (w <= 0) || ( h <= 0 ) ) goto RotateDIB; SIN_ALPHA = sin( (double)angle * 3.14159265 / 180 );
    COS_ALPHA = cos( (double)angle * 3.14159265 / 180 );
    // calculate corner scale
    xc[0] = 0; 
    yc[0] = 0;
    xc[1] = (int)( (double)w * COS_ALPHA ); 
    yc[1] =-(int)( (double)w * SIN_ALPHA );
    xc[2] = (int)( (double)w * COS_ALPHA+(double)h * SIN_ALPHA ); 
    yc[2] = (int)(-(double)w * SIN_ALPHA+(double)h * COS_ALPHA );
    xc[3] = (int)( (double)h * SIN_ALPHA );
    yc[3] = (int)( (double)h * COS_ALPHA );// calculate rectangle size
    maxX = max( xc[ 0 ], xc[ 1 ] );
    maxX = max( maxX, xc[ 2 ] );
    maxX = max( maxX, xc[ 3 ] );
    minX = min( xc[ 0 ], xc[ 1 ] );
    minX = min( minX, xc[ 2 ] );
    minX = min( minX, xc[ 3 ] );
    maxY = max( yc[ 0 ], yc[ 1 ] );
    maxY = max( maxY, yc[ 2 ] );
    maxY = max( maxY, yc[ 3 ] );
    minY = min( yc[ 0 ], yc[ 1 ] );
    minY = min( minY, yc[ 2 ] );
    minY = min( minY, yc[ 3 ] );// calculate offset of orign point and move it
    offsetX = minX; offsetY = minY; maxX -= offsetX; maxY -= offsetY;
    // calculate memory size
    nBytesPerLine = ( (lpDIBHdr->bmiHeader.biBitCount) * 
        (maxX+1) + 31 ) / 32 * 4;
    size = ((DWORD)nBytesPerLine) * (DWORD)(maxY+1);
    // alloc memory
    ret = (HDIB)::GlobalAlloc( GHND, size + sizeh );
    if( ret == NULL ){
    AfxMessageBox( "メモリ不足!" );
    goto RotateDIB;
    }
    // initialize the new HDIB
    lpDib1 = (LPSTR) ::GlobalLock( ret );
    lpDIBHdr1 = (LPBITMAPINFO)lpDib1;
    memcpy( lpDib1, lpDib, sizeh );
    lpDIBHdr1->bmiHeader.biWidth = maxX+1;
    lpDIBHdr1->bmiHeader.biHeight = maxY+1;
    lpDIBHdr1->bmiHeader.biSizeImage = size;
    // To rotate it
    for( pt2.y = 0; pt2.y <= maxY; pt2.y ++ )
    for( pt2.x = 0; pt2.x <= maxX; pt2.x ++ ){
    double x =   (double)(pt2.x+offsetX) * COS_ALPHA
    -(double)(pt2.y+offsetY) * SIN_ALPHA;
    double y =   (double)(pt2.x+offsetX) * SIN_ALPHA
    +(double)(pt2.y+offsetY) * COS_ALPHA;
    if( ( (int)x < 0 ) ||
    ( (int)x >= w ) ||
    ( (int)y < 0 ) ||
    ( (int)y >= h ) ){
    SetDIBxy( lpDib1, pt2, fill );
    }
    else{
    pt1.x = (int) x;
    pt1.y = (int) y;
    SetDIBxy( lpDib1, pt2, GetDIBxy( lpDib, pt1 ) );
    }
    }RotateDIB:
    GlobalUnlock( (HGLOBAL)org );
    if( ret != NULL ) GlobalUnlock( (HGLOBAL)ret );
    return ret;
    }CDIB* WINAPI RotateDib( CDIB* org, int angle, DWORD fill)
    {
    if( org == NULL ) return NULL;
    if( org->hDib == NULL ) return NULL;
    HDIB hNewDib = ::RotateDib( org->hDib, angle, fill );
    CDIB *newDib = new CDIB( hNewDib );
    if( newDib == NULL )
    ::GlobalDelete( hNewDib );
    return newDib;
    }CTDIB* WINAPI RotateDib( CDIB* org, int angle )
    {
    if( org == NULL ) return NULL;
    CTDIB* newDib = new CTDIB( RGB( 0xff,0xff,0xff ) );
    if( newDib == NULL ) return NULL; LPSTR lpDib = (LPSTR) ::GlobalLock( (HGLOBAL)(org->hDib) );
    LPSTR lpDib1 = NULL;
    UINT fill = org->Pal.GetNearestPaletteIndex( RGB(0xff,0xff,0xff) );
    CPoint pt1,pt2;
    LPBITMAPINFO lpDIBHdr = (LPBITMAPINFO)lpDib;
    LPBITMAPINFO lpDIBHdr1 = NULL;
    LPBITMAPINFO lpDIBHdrAnd = NULL;
    LPBITMAPINFO lpDIBHdrOr = NULL; 
    HDIB ret = NULL;
    HDIB hAnd = NULL;
    HDIB hOr = NULL;
    int w = (int)DIBWidth( lpDib );
    int h = (int)DIBHeight( lpDib );
    int nBytesPerLine;
    int maxX,maxY,minX,minY,offsetX,offsetY;
    DWORD size;
    int sizeh = sizeof(BITMAPINFOHEADER)
    +sizeof(RGBQUAD)*DIBNumColors(lpDib);
    double SIN_ALPHA;
    double COS_ALPHA;
    int xc[4];
    int yc[4]; if( (w <= 0) || ( h <= 0 ) ) goto RotateDIB1; SIN_ALPHA = sin( (double)angle * 3.14159265 / 180 );
    COS_ALPHA = cos( (double)angle * 3.14159265 / 180 );
    // calculate corner scale
    xc[0] = 0; 
    yc[0] = 0;
    xc[1] = (int)( (double)w * COS_ALPHA ); 
    yc[1] =-(int)( (double)w * SIN_ALPHA );
    xc[2] = (int)( (double)w * COS_ALPHA+(double)h * SIN_ALPHA ); 
    yc[2] = (int)(-(double)w * SIN_ALPHA+(double)h * COS_ALPHA );
    xc[3] = (int)( (double)h * SIN_ALPHA );
    yc[3] = (int)( (double)h * COS_ALPHA );// calculate rectangle size
    maxX = max( xc[ 0 ], xc[ 1 ] );
    maxX = max( maxX, xc[ 2 ] );
    maxX = max( maxX, xc[ 3 ] );
    minX = min( xc[ 0 ], xc[ 1 ] );
    minX = min( minX, xc[ 2 ] );
    minX = min( minX, xc[ 3 ] );
    maxY = max( yc[ 0 ], yc[ 1 ] );
    maxY = max( maxY, yc[ 2 ] );
    maxY = max( maxY, yc[ 3 ] );
    minY = min( yc[ 0 ], yc[ 1 ] );
    minY = min( minY, yc[ 2 ] );
    minY = min( minY, yc[ 3 ] );// calculate offset of orign point and move it
    offsetX = minX; offsetY = minY; maxX -= offsetX; maxY -= offsetY;
    // calculate memory size
    nBytesPerLine = ( (lpDIBHdr->bmiHeader.biBitCount) * 
        (maxX+1) + 31 ) / 32 * 4;
    size = ((DWORD)nBytesPerLine) * ((DWORD)(maxY+1));
    // alloc memory
    ret = (HDIB)::GlobalAlloc( GHND, size + sizeh );
    if( ret == NULL ){
    AfxMessageBox( "メモリ不足!(RotateDib[CDIB->CTDIB] main handle)" );
    goto RotateDIB1;
    }
    // initialize the new HDIB
    lpDib1 = (LPSTR) ::GlobalLock( ret );
    lpDIBHdr1 = (LPBITMAPINFO)lpDib1;
    memcpy( lpDib1, lpDib, sizeh );
    lpDIBHdr1->bmiHeader.biWidth = maxX+1;
    lpDIBHdr1->bmiHeader.biHeight = maxY+1;
    lpDIBHdr1->bmiHeader.biSizeImage = size;
    hAnd = (HDIB)::CopyHandle( ret );
    hOr = (HDIB)::CopyHandle( ret );
    if( (hAnd == NULL) || (hOr == NULL) ){
    AfxMessageBox( "メモリ不足! And/Or handle" );
    goto RotateDIB1;
    }
    lpDIBHdrAnd = (LPBITMAPINFO)::GlobalLock( hAnd );
    lpDIBHdrOr  = (LPBITMAPINFO)::GlobalLock( hOr );
    // To rotate it
    for( pt2.y = 0; pt2.y <= maxY; pt2.y ++ )
    for( pt2.x = 0; pt2.x <= maxX; pt2.x ++ ){
    double x =   (double)(pt2.x+offsetX) * COS_ALPHA
    -(double)(pt2.y+offsetY) * SIN_ALPHA;
    double y =   (double)(pt2.x+offsetX) * SIN_ALPHA
    +(double)(pt2.y+offsetY) * COS_ALPHA;
    if( ( (int)x < 0 ) ||
    ( (int)x >= w ) ||
    ( (int)y < 0 ) ||
    ( (int)y >= h ) ){
    SetDIBxy( lpDib1, pt2, fill );
    SetDIBxy( (LPSTR)lpDIBHdrAnd, pt2, 0xff );
    SetDIBxy( (LPSTR)lpDIBHdrOr,  pt2, 0x00 );
    }
    else{
    pt1.x = (int) x;
    pt1.y = (int) y;
    DWORD temp = GetDIBxy( lpDib, pt1 );
    SetDIBxy( lpDib1, pt2, temp );
    SetDIBxy( (LPSTR)lpDIBHdrAnd, pt2, 0x00 );
    SetDIBxy( (LPSTR)lpDIBHdrOr,  pt2, temp );
    }
    }RotateDIB1:
    GlobalUnlock( (HGLOBAL)(org->hDib) );
    if( ret != NULL )
    GlobalUnlock( (HGLOBAL)ret );
    if( hAnd != NULL )
    GlobalUnlock( (HGLOBAL)hAnd );
    if( hOr != NULL )
    GlobalUnlock( (HGLOBAL)hOr ); if( (ret == NULL) || (hAnd == NULL) || (hOr == NULL) ){
    if( ret != NULL ){ ::GlobalDelete((HGLOBAL)ret); ret = NULL; }
    if( hAnd != NULL ){ ::GlobalDelete((HGLOBAL)hAnd); hAnd = NULL; }
    if( hOr != NULL ){ ::GlobalDelete((HGLOBAL)hOr); hOr = NULL; }
    } if( ret != NULL ){
    newDib->hDib = ret;
    newDib->hFlag = ret;
    newDib->hAndDib = hAnd;
    newDib->hOrDib = hOr;
    return newDib;
    }
    else{
    delete newDib;
    return NULL;
    }
    }CTDIB* WINAPI RotateDib( CTDIB* org,int angle )
    {
    if( org == NULL ) return NULL;
    if( org->hDib == NULL ) return NULL;
    UINT index = org->Pal.GetNearestPaletteIndex( org->tc );
    HDIB hNewDib = ::RotateDib( org->hDib, angle, index );
    CTDIB *newDib = new CTDIB( org->tc, hNewDib );
    if( newDib == NULL )
    ::GlobalDelete( hNewDib );
    return newDib;
    }//use these as you like