Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как повернуть Bitmap на любой угол

Delphi , Графика и Игры , Bitmap

Как повернуть Bitmap на любой угол



const
  PixelMax = 32768;

type
  pPixelArray = ^TPixelArray;
  TPixelArray = array [0..PixelMax-1] of TRGBTriple;

procedure RotateBitmap_ads(SourceBitmap: TBitmap;
out DestBitmap: TBitmap; Center: TPoint; Angle: Double);
var
  cosRadians : Double;
  inX : Integer;
  inXOriginal : Integer;
  inXPrime : Integer;
  inXPrimeRotated : Integer;
  inY : Integer;
  inYOriginal : Integer;
  inYPrime : Integer;
  inYPrimeRotated : Integer;
  OriginalRow : pPixelArray;
  Radians : Double;
  RotatedRow : pPixelArray;
  sinRadians : Double;
begin
  DestBitmap.Width := SourceBitmap.Width;
  DestBitmap.Height := SourceBitmap.Height;
  DestBitmap.PixelFormat := pf24bit;
  Radians := -(Angle) * PI / 180;
  sinRadians := Sin(Radians);
  cosRadians := Cos(Radians);
  for inX := DestBitmap.Height-1 downto 0 do
  begin
    RotatedRow := DestBitmap.Scanline[inX];
    inXPrime := 2*(inX - Center.y) + 1;
    for inY := DestBitmap.Width-1 downto 0 do
    begin
      inYPrime := 2*(inY - Center.x) + 1;
      inYPrimeRotated := Round(inYPrime * CosRadians - inXPrime * sinRadians);
      inXPrimeRotated := Round(inYPrime * sinRadians + inXPrime * cosRadians);
      inYOriginal := (inYPrimeRotated - 1) div 2 + Center.x;
      inXOriginal := (inXPrimeRotated - 1) div 2 + Center.y;
      if (inYOriginal >= 0) and (inYOriginal <= SourceBitmap.Width-1) and
      (inXOriginal >= 0) and (inXOriginal <= SourceBitmap.Height-1) then
      begin
        OriginalRow := SourceBitmap.Scanline[inXOriginal];
        RotatedRow[inY] := OriginalRow[inYOriginal]
      end
      else
      begin
        RotatedRow[inY].rgbtBlue := 255;
        RotatedRow[inY].rgbtGreen := 0;
        RotatedRow[inY].rgbtRed := 0
      end;
    end;
  end;
end;

{Usage:}
procedure TForm1.Button1Click(Sender: TObject);
var
  Center : TPoint;
  Bitmap : TBitmap;
begin
  Bitmap := TBitmap.Create;
  try
    Center.y := (Image.Height div 2)+20;
    Center.x := (Image.Width div 2)+0;
    RotateBitmap_ads(
    Image.Picture.Bitmap,
    Bitmap,
    Center,
    Angle);
    Angle := Angle + 15;
    Image2.Picture.Bitmap.Assign(Bitmap);
  finally
    Bitmap.Free;
  end;
end;

Перевод контента на русский язык:

Данное кодирование - это программный проект Delphi, который вращает изображение (представленное как объект TBitmap) вокруг его центра по указанному углу. Вращение достигается с помощью формулы Родригеса, которая является математической формулой для вращения вектора в 3D-пространстве.

Вот разбивка кода:

  1. Процедура RotateBitmap_ads принимает четыре параметра: SourceBitmap, DestBitmap, Center и Angle. Она вращает SourceBitmap вокруг его центра по указанному углу.
  2. Процедура сначала вычисляет синус и косинус угла вращения с помощью функций Sin и Cos.
  3. Затем она проходит через каждый пиксель в целевой битмапке (которая имеет размер, равный размеру исходной битмапки).
  4. Для каждого пикселя она вычисляет его оригинальную позицию в исходной битмапке, отняв центрные координаты от текущих координат пикселя.
  5. Процедура затем применяет формулу Родригеса для вращения оригинальных координат пикселя вокруг начала координат (0, 0) и вычисляет новые координаты пикселя.
  6. Если новые координаты пикселя попадают в пределы исходной битмапки, она копирует значение пикселя из исходной битмапки в целевую битмапку на соответствующей позиции. В противном случае она устанавливает значение пикселя в черное (rgbRed = 0, rgbGreen = 0 и rgbBlue = 0).
  7. Процедура события Button1Click создает новый объект TBitmap, вращает изображение с помощью процедуры RotateBitmap_ads, а затем присваивает вращенное изображение другому объекту TBitmap (Image2). Она увеличивает угол вращения на 15 градусов каждый раз, когда кнопка нажимается.

Код можно улучшить следующими способами:

  1. Обработка ошибок: код не обрабатывает ошибки, которые могут возникнуть при обработке изображений. Нужно добавить блоки try-catch для ловли и обработки исключений.
  2. Оптимизация производительности: код использует вложенные циклы, что может быть медленным для больших изображений. Рассмотрите возможность использования параллельного процесса или оптимизации алгоритма вращения для лучшей производительности.
  3. Организация кода: процедура RotateBitmap_ads является слишком длинной и сложной. Может быть желательно разбить ее на более маленькие процедуры или классы для лучшей поддержки.
  4. Документация: код не содержит комментариев и документации, что делает его трудным для понимания для других, которые могут работать над проектом в будущем.

Вот альтернативное решение с использованием функциональности вращения битмапок Delphi:

procedure TForm1.Button1Click(Sender: TObject);
var
  Center: TPoint;
  Bitmap: TBitmap;
begin
  Bitmap := TBitmap.Create;
  try
    Center.y := (Image.Height div 2) + 20;
    Center.x := (Image.Width div 2) + 0;
    Bitmap.Assign(Image.Picture.Bitmap);
    Bitmap.Rotate(Angle, Center);
    Image2.Picture.Bitmap.Assign(Bitmap);
  finally
    Bitmap.Free;
  end;
end;

В этом коде создается новый объект TBitmap, присваивается исходное изображение, вращается битмапка с помощью метода Rotate и присваивается вращенное изображение другому объекту TBitmap (Image2). Угол вращения увеличивается на 15 градусов каждый раз, когда кнопка нажимается.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Bitmap ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-01-29 03:45:11/0.0037000179290771/0