2009-05-28 4 views
6

Я пытаюсь центрировать повернутое изображение в буфер назначения, используя GDI +. Буфер источника и буфер назначения имеют разные размеры.Как центрировать повернутое изображение с помощью GDI +?

Исходный буфер - это размер данных изображения: (ширина, высота).
Буфер назначения - размер прямоугольника, необходимого для соответствия всего повернутое изображение: (rotatedWidth, rotatedHeight).

Это код, который я пытаюсь:

// 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); 

Это почти работы. Это близко - я нахожу, если высота больше ширина, левая позиция повернутого изображения неверна. Аналогично, если ширина больше высота, верхнее положение повернутого изображения неверно.

Некоторые примечания:

  • IPMathUtilities утилита класса я написал.
  • Я на 100% уверен, что IPMathUtilities::CalculateRotatedImageSize() рассчитывает правильный размер прямоугольника, необходимого для полного поворота изображения. 100% уверены. Я проверил его полностью, и он работает.
  • Я недавно задал аналогичный вопрос: Why is iplRotate() not giving me correct results?. Я закончил отказ от IPL/IPP и попытку GDI +.

Любые идеи?

ответ

5

После поворота сначала переместите изображение в исходное положение, затем дополнительно на половину разницы новое полотно больше. Если ваш расчет в CalculateRotatedImageSize действительно правильный, он должен тогда точно соответствовать. Просто тестировал этот код и он, кажется, работает:

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: извините, конечно

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); 

действительно так же, как

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

который только код, который вы в курсе. Кажется, все работает отлично.

EDIT2: возможно, ошибка просто

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

Попробуйте

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

вместо

+0

Ваш первый блок кода было то, что я пропал без вести - перевод назад от начала координат пространства изображения источника - это недостающий ключ. Огромное спасибо. Я настолько рад, что имею центрированные изображения. Спасибо! –

+0

, но это: g.TranslateTransform ((float) (org.Width/-2), (float) (орг.Высота/-2)); g.RotateTransform (45, System.Drawing.Drawing2D.MatrixOrder.Append); g.TranslateTransform ((float) (вращение. Ширина/2), (поплавок) (вращение. Высота/2), System.Drawing.Drawing2D.MatrixOrder.Append); g.DrawImage (org, 0, 0); работает для меня. Разве это не эквивалентно коду, который вы опубликовали. В любом случае, рад, что он работает сейчас :) –

+0

Я не думаю, что это эквивалентно - в моем исходном коде после поворота меня перевели прямо в место для изображения цели. В вашем коде вы переводите сначала обратно в исходное пространство изображения, а затем в место назначения изображения. У вас есть дополнительный перевод, которого я не видел. :-) –

Смежные вопросы