2009-05-28 34 views
6

Tôi đang cố gắng căn giữa hình ảnh được xoay vào bộ đệm đích bằng GDI +. Bộ đệm nguồn và bộ đệm đích là các kích cỡ khác nhau.Làm cách nào để căn giữa hình ảnh được xoay bằng GDI +?

Bộ đệm nguồn là kích thước của dữ liệu hình ảnh: (chiều rộng, chiều cao).
Bộ đệm đích là kích thước của hình chữ nhật được yêu cầu để phù hợp với toàn bộ hình ảnh được xoay: (xoayĐộ sáng, xoay vòng).

Đây là mã Tôi đang cố gắng:

// Calculate the size needed for the image to be rotated into 
int width = /* some width */; 
int height = /* some height */; 
System::Windows::Size destSize 
    = IPMathUtilities::CalculateRotatedImageSize(rotateAreaBoundingPoints, 
    rotationDegree, width, height); 

// 
// Create source bitmap object 
Bitmap^ sourceBitmap = gcnew Bitmap(width, height, width * 2, 
    PixelFormat::Format16bppRgb555, ptrSourceBuffer); 

// 
// Create destination bitmap object 
int destBufferSize = destSize.Width * destSize.Height * 2; 
BYTE* pDestBuffer = new BYTE[destBufferSize]; 
memset(pDestBuffer, 0, destBufferSize); 
Bitmap^ destBitmap = gcnew Bitmap(destSize.Width, destSize.Height, 
    destSize.Width * 2, PixelFormat::Format16bppRgb555, (IntPtr)pDestBuffer); 

// 
// Draw rotated source image in destination image 
Graphics^ g = Graphics::FromImage(destBitmap); 
g->TranslateTransform(-width/2, -height/2); 
g->RotateTransform(rotationDegree, MatrixOrder::Append); 
g->TranslateTransform(destSize.Width/2.0, destSize.Height/2.0, 
    MatrixOrder::Append); 
g->DrawImage(sourceBitmap, 0, 0, width, height); 

này gần công trình. It's close - Tôi đang tìm kiếm nếu chiều cao lớn hơn chiều rộng, vị trí bên trái của hình ảnh được xoay không chính xác. Tương tự, nếu chiều rộng lớn hơn chiều cao, vị trí trên cùng của hình ảnh được xoay không chính xác.

Một số lưu ý:

  • IPMathUtilities là một lớp tiện ích tôi đã viết.
  • Tôi hoàn toàn 100% rằng IPMathUtilities::CalculateRotatedImageSize() tính toán kích thước chính xác của hình chữ nhật được yêu cầu để vừa với toàn bộ hình ảnh được xoay. Chắc chắn 100%. Tôi đã thử nghiệm nó kỹ lưỡng và nó hoạt động.
  • Gần đây tôi đã hỏi một câu hỏi tương tự: Why is iplRotate() not giving me correct results?. Tôi đã kết thúc từ bỏ IPL/IPP và thử GDI +.

Bất kỳ ý tưởng nào?

Trả lời

5

Sau khi xoay, trước tiên hãy di chuyển hình ảnh trở lại vị trí ban đầu, sau đó thêm một nửa sự khác biệt của canvas mới lớn hơn. Nếu tính toán của bạn trong CalculateRotatedImageSize thực sự là chính xác, thì nó sẽ khớp chính xác. Chỉ cần kiểm tra mã này và nó dường như làm việc:

g.TranslateTransform((float)(org.Width/-2), (float)(org.Height/-2)); 
g.RotateTransform(45, System.Drawing.Drawing2D.MatrixOrder.Append); 
g.TranslateTransform((float)(org.Width/2), (float)(org.Height/2), System.Drawing.Drawing2D.MatrixOrder.Append); 
g.TranslateTransform((float)((rotated.Width - org.Width)/2), (float)((rotated.Height - org.Height)/2), System.Drawing.Drawing2D.MatrixOrder.Append); 

EDIT: xin lỗi, tất nhiên

g.TranslateTransform((float)(org.Width/2), (float)(org.Height/2), System.Drawing.Drawing2D.MatrixOrder.Append); 
g.TranslateTransform((float)((rotated.Width - org.Width)/2), (float)((rotated.Height - org.Height)/2), System.Drawing.Drawing2D.MatrixOrder.Append); 

thực sự là giống như

g.TranslateTransform((float)(rotated.Width/2), (float)(rotated.Height/2), System.Drawing.Drawing2D.MatrixOrder.Append); 

mà chỉ là mã bạn được đăng. Dường như làm việc tốt cho tôi mặc dù.

EDIT2: có lẽ lỗi là chỉ

g->DrawImage(sourceBitmap, 0, 0, width, height); 

Hãy thử

g->DrawImage(sourceBitmap, 0, 0); 

thay

+0

khối mã đầu tiên của bạn có một cái gì đó tôi đã mất tích - bản dịch lại từ nguồn gốc đến không gian hình ảnh nguồn - đó là chìa khóa còn thiếu. Cảm ơn bạn rất nhiều. Tôi rất nhẹ nhõm khi có hình ảnh xoay vòng giữa. Cảm ơn bạn! –

+0

nhưng điều này: g.TranslateTransform ((float) (org.Width/-2), (float) (org.Chiều cao/-2)); g.RotateTransform (45, System.Drawing.Drawing2D.MatrixOrder.Append); g.TranslateTransform ((phao) (xoay vòng.Width/2), (phao) (xoay.Height/2), System.Drawing.Drawing2D.MatrixOrder.Append); g.DrawImage (org, 0, 0); phù hợp với tôi. Điều đó không chỉ tương đương với mã bạn đã đăng. Dù sao, vui mừng nó hoạt động ngay bây giờ :) –

+0

Tôi không nghĩ rằng nó tương đương - trong mã ban đầu của tôi, sau khi xoay, tôi đã được dịch trực tiếp đến không gian hình ảnh đích. Trong mã của bạn, bạn đang dịch lần đầu tiên trở lại không gian hình ảnh nguồn, sau đó đến không gian hình ảnh đích. Bạn có một bản dịch bổ sung, đó là những gì tôi đã mất tích. :-) –

Các vấn đề liên quan