In the first you have to rotate 4 corners of image then compute rectangle of rotated points.
In the following code you have to call bhRotateImage for rotate of image.

```
#define BH_DEG_TO_RAD CV_PI/180
#define BH_RAD_TO_DEG 180/CV_PI
typedef unsigned int UINT;
#define BH_MAXUINT ((UINT)~((UINT)0))
#define BH_MAXINT ((int)(BH_MAXUINT >> 1))
typedef vector<CvPoint2D32f> BhPoints32f;
CvSize bhGetRectSize(const CvRect srcRect)
{
return cvSize(srcRect.width,srcRect.height);
}
BH_RECT bhBlankRECT()
{
BH_RECT res;
res.left = BH_MAXINT;
res.top = BH_MAXINT;
res.bottom = 0;
res.right = 0;
return res;
}
int bhLineLength(CvPoint p1,CvPoint p2)
{
int res ;
if ( (p2.x == p1.x) && (p2.y == p1.y))
res = 0;
else if (p2.x == p1.x)
res = abs(p2.y - p1.y);
else if (p2.y == p1.y)
res = abs(p2.x - p1.x);
else
res = cvRound( sqrt(pow((float)p2.y-p1.y,2) + pow((float)p2.x-p1.x,2)));
return res;
}
float bhGetLineAngle(CvPoint p1, CvPoint p2)
{
float deg = float( atan2( (float)(p2.y - p1.y) , (float)(p2.x - p1.x)) * BH_RAD_TO_DEG );
if (deg < 0)
deg = 360 + deg;
return deg;
}
CvRect bhGetImageCvRect(const IplImage* srcImage)
{
return cvRect(0,0,srcImage->width,srcImage->height);
}
BhPoints32f bhGetRectPoints(CvRect srcRect)
{
BhPoints32f result;
result.push_back(cvPoint2D32f(srcRect.x,srcRect.y));
result.push_back(cvPoint2D32f(srcRect.x + srcRect.width,srcRect.y));
result.push_back(cvPoint2D32f(srcRect.x + srcRect.width ,srcRect.y + srcRect.height));
result.push_back(cvPoint2D32f(srcRect.x,srcRect.y + srcRect.height));
return result;
}
CvPoint2D32f bhRotatePoint(CvPoint2D32f srcPoint,CvPoint2D32f center,float angle)
{
int rad = bhLineLength(cvPointFrom32f(srcPoint),cvPointFrom32f(center));
float teta = bhGetLineAngle(cvPointFrom32f(center),cvPointFrom32f(srcPoint));
CvPoint2D32f result;
float newTeta = angle + teta;
result.x = center.x + cvRound( rad * cos(newTeta * BH_DEG_TO_RAD));
result.y = center.y + cvRound( rad * sin(newTeta * BH_DEG_TO_RAD));
return result;
}
void bhRotatePoints(BhPoints32f& srcPoints,CvPoint2D32f center,float angle)
{
for (unsigned int i =0 ; i < srcPoints.size();i++)
{
srcPoints[i] = bhRotatePoint(srcPoints[i],center,angle);
}
}
CvRect bhGetPoints32fCVRect(BhPoints32f points)
{
BH_RECT r = bhBlankRECT();
for (unsigned int i=0; i < points.size() ;i++)
{
if (points[i].x < r.left)
r.left = (int) points[i].x;
if (points[i].x > r.right)
r.right = (int)points[i].x;
if (points[i].y < r.top)
r.top = (int)points[i].y;
if (points[i].y > r.bottom)
r.bottom = (int)points[i].y;
}
return bhRect2CvRect(r);
}
CvPoint bhGetImageCenter(const IplImage* srcImage)
{
return cvPoint(srcImage->width/2,srcImage->height/2);
}
IplImage* bhRotateImage(const IplImage* srcImage,CvPoint center,double angle,CvScalar fillval ,CvPoint& offsetPoint,int flags )
{
CvMat* rot_mat = cvCreateMat(2,3,CV_32FC1);
cv2DRotationMatrix(cvPointTo32f( center), angle, 1, rot_mat );
IplImage* resultImage = NULL;
CvRect imageRect = bhGetImageCvRect(srcImage);
BhPoints32f rectPoints = bhGetRectPoints(imageRect);
bhRotatePoints(rectPoints,cvPointTo32f(center),float(-angle));
CvRect rotateRect = bhGetPoints32fCVRect(rectPoints);
CV_MAT_ELEM(*rot_mat,float,0,2) = CV_MAT_ELEM(*rot_mat,float,0,2) - rotateRect.x;
CV_MAT_ELEM(*rot_mat,float,1,2) = CV_MAT_ELEM(*rot_mat,float,1,2) - rotateRect.y;
resultImage = cvCreateImage(bhGetRectSize(rotateRect),srcImage->depth,srcImage->nChannels);
cvSetImageROI(resultImage,bhGetImageCvRect(resultImage));
cvWarpAffine( srcImage, resultImage, rot_mat ,flags,fillval);
cvResetImageROI(resultImage);
offsetPoint = cvPoint(rotateRect.x,rotateRect.y);
CvPoint preCenter = bhGetImageCenter(srcImage);
CvPoint curCenter = bhGetImageCenter(resultImage);
offsetPoint = cvPoint(curCenter.x - preCenter.x , curCenter.y - preCenter.y ...
```

(more)