Преобразование (вращение) изображения с использованием матрицы - результаты рендеринга времени разработки и времени выполнения - PullRequest
3 голосов
/ 14 июля 2009

У меня есть изображение 48x48, которое поворачивается с использованием матрицы преобразования.

По некоторым причинам повернутое изображение во время разработки отличается от повернутого изображения во время выполнения, как вы можете видеть из этого снимка экрана (ссылка не работает) (время разработки слева, время выполнения справа):

Это может быть немного трудно определить, но если вы внимательно посмотрите на правый край синего круга, он будет примерно на пиксель шире на изображении справа. Обратите внимание, что изображение является многослойным - белое свечение на переднем плане - это та часть, которая вращается, а синий шар на заднем плане неподвижен.

Кажется, что изображение смещено на 1 пиксель во время выполнения при повороте точно на 90 градусов (как на скриншоте), на 180 градусов и, вероятно, также на 270 градусов. Насколько я вижу, изображение выглядит одинаково с любым другим углом поворота.

Вот фрагмент:

protected static Image RotateImage(Image pImage, Single pAngle)
    {
      Matrix lMatrix = new Matrix();
      lMatrix.RotateAt(pAngle, new PointF(pImage.Width / 2, pImage.Height / 2));
      Bitmap lNewBitmap = new Bitmap(pImage.Width, pImage.Height);
      lNewBitmap.SetResolution(pImage.HorizontalResolution, pImage.VerticalResolution);
      Graphics lGraphics = Graphics.FromImage(lNewBitmap);
      lGraphics.Transform = lMatrix;
      lGraphics.DrawImage(pImage, 0, 0);
      lGraphics.Dispose();
      lMatrix.Dispose();
      return lNewBitmap;
    }

    void SomeMethod()
    {
      // Same results in design-time and run-time:
      PictureBox1.Image = RotateImage(PictureBox2.Image, 18)
      // Different results in design-time and run-time.
      PictureBox1.Image = RotateImage(PictureBox2.Image, 90)
    }

Может кто-нибудь объяснить причину такого поведения? Или, что еще лучше, решение, позволяющее сделать результаты во время выполнения похожими на результаты во время разработки?

Это важно для меня, потому что это изображение является частью анимации, которая генерируется из кода на основе одного изображения, которое затем вращается небольшими шагами. Во время разработки анимация выглядит плавно и красиво. Во время выполнения похоже, что он прыгает вокруг: /

Я использую Visual Studio 2005 в Windows Vista Business SP2.

Ответы [ 4 ]

3 голосов
/ 14 июля 2009

Это может быть связано с различиями в объекте Graphics, используемом во время разработки, и во время выполнения, например PixelOffsetMode.

0 голосов
/ 14 июля 2009

Я думаю, что это должно быть проблемой для математики, выполняемой с плавающей запятой; при округлении до целочисленных координат.

Один вопрос, который может быть актуален ... Ваше изображение полностью квадратное, а ширина и высота - четное число? Может быть, проблема в этом.

Редактировать : В первом чтении я прошел размеры изображения ... Если бы это не было проблемой, возможно, вы могли бы сделать простое вращение самостоятельно:

angle = 90 : img[i][j] = img[j][w-i]
angle = 180: img[i][j] = img[w-i][w-j]
angle = 270: img[i][j] = img[w-j][i]

(я думаю, что с индексами все в порядке, но двойная проверка не будет плохой)

0 голосов
/ 14 июля 2009

Хм, мое соображение состоит в том, чтобы попробовать:

lMatrix.RotateAt(pAngle, new PointF((pImage.Width + 1)/2.0f, (pImage.Height + 1)/ 2.0f));
0 голосов
/ 14 июля 2009

Как вы определяете угол поворота? в градусах или в радианах?

Иногда я получаю результаты, подобные тем, которые вы описываете, когда я случайно указал свой угол в градусах, когда это должны были быть радианы (и в результате объект был повернут на несколько сотен градусов вместо нескольких)

Не знаю точно, учитывая ваш конкретный пример, но его стоит предложить.

...