Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 10.03.2015, 10:36
Rusland Rusland вне форума
Прохожий
 
Регистрация: 12.10.2010
Сообщения: 25
Репутация: 10
По умолчанию Вращение PNG

Добрый день.
На просторах сети нашел процедуру вращения PNG

Код:
procedure DrawPngRotate(const AOriginal: TPNGImage; ARotated: TPNGImage;
  const AAngle: single);
type
  TRGBTripleArray = array [0..32767] of TRGBTriple;
  pRGBTripleArray = ^TRGBTripleArray;
var
  TmpPng: TPngImage;
  TmpX: Integer;
  TmpY: Integer;
  TmpXOrig: Integer;
  TmpYOrig: Integer;
  TmpXPrime: Integer;
  TmpYPrime: Integer;
  TmpDelta: single;
  TmpDeltaCos: single;
  TmpDeltaSin: single;
  TmpWidth: Integer;
  TmpHeight: Integer;
  TmpRowRot : Integer;
  TmpRowOrg : Integer;
  TmpRowStart : Pointer;
  TmpRowRotated: pRGBtripleArray;
  TmpAlphaRot : Integer;
  TmpAlphaOrg : Integer;
  TmpAlphaStart : Pointer;
  TmpAlphaRotated : pByteArray;
  TmpTransparent: TRGBTriple;
  TmpSubX: Integer;
  TmpSubY: Integer;
  TmpRotX: Integer;
  TmpRotY: Integer;
  // Diametr mod by angle
  function Mod360(const AAngle: single): single;
  begin
    Result := Frac(AAngle / 360) * 360;
    if Result < 0 then Result := Result + 360;
  end;
  function Max(a,b:integer):integer;
  begin
    if (a>=b) then Result:=a
    else Result:=b;
  end;
begin
  TmpDelta := -(2 * pi * Mod360(AAngle)) / 360;
  TmpDeltaSin := Sin(TmpDelta);
  TmpDeltaCos := Cos(TmpDelta);
  TmpWidth  := Abs(Round(AOriginal.Height * TmpDeltaSin))
    + Abs(Round(AOriginal.Width * TmpDeltaCos));
  TmpHeight := Abs(Round(AOriginal.Width * TmpDeltaSin))
    + Abs(Round(AOriginal.Height * TmpDeltaCos));
  // Rotate by zero
  if (Abs(TmpDelta) * Max(AOriginal.Width, AOriginal.Height)) <= 1 then
  begin
    if ARotated <> AOriginal then ARotated.Assign(AOriginal);
    Exit;
  end;

  // Rotate by non-zero
  TmpPng := TPngImage.CreateBlank(AOriginal.Header.ColorType, 8, TmpWidth, TmpHeight);
  try
    TmpRotY := Pred(TmpWidth);
    TmpRotX := Pred(TmpHeight);
    TmpSubY := Pred(AOriginal.Width);
    TmpSubX := Pred(AOriginal.Height);
    TmpRowRotated := TmpPng.Scanline[TmpRotX] ;
    TmpRowStart := AOriginal.Scanline[0];
    TmpRowRot := Integer(TmpPng.ScanLine[1]) - Integer(TmpPng.ScanLine[0]);
    TmpRowOrg := Integer(AOriginal.ScanLine[1]) - Integer(AOriginal.ScanLine[0]);
    TmpTransparent := pRGBtripleArray(AOriginal.Scanline[TmpSubX])[0];
    // Check for transparency
    if AOriginal.Header.ColorType in [COLOR_RGBALPHA] then
    begin
      TmpAlphaStart := AOriginal.AlphaScanline[0];
      TmpAlphaRotated := TmpPng.AlphaScanline[TmpRotX];
      TmpAlphaRot := Integer(TmpPng.AlphaScanline[1]) 
        - Integer(TmpPng.AlphaScanline[0]);
      TmpAlphaOrg := Integer(AOriginal.AlphaScanline[1]) 
        - Integer(AOriginal.AlphaScanline[0]);
    end else begin
      TmpAlphaStart := nil;
      TmpAlphaRotated := nil;
      TmpAlphaRot := 0;
      TmpAlphaOrg := 0;
    end;

    for TmpY := TmpRotX downto 0 do
    begin
      TmpYPrime := 2 * TmpY - TmpHeight + 1;
      for TmpX := TmpRotY downto 0 do
      begin
        TmpXPrime := 2 * TmpX - TmpWidth + 1;
        TmpXOrig := (Round(TmpXPrime * TmpDeltaCos - TmpYPrime * TmpDeltaSin)
          + TmpSubY) div 2;
        // If inside
        if (TmpXOrig >= 0) and (TmpXOrig <= TmpSubY) then
        begin
          TmpYOrig := (Round(TmpXPrime * TmpDeltaSin + TmpYPrime*TmpDeltaCos)
            + TmpSubX) div 2 ;
          if (TmpYOrig >= 0) and (TmpYOrig <= TmpSubX) then
          begin
            TmpRowRotated[TmpX] := pRGBTripleArray(Integer(TmpRowStart)
              + (TmpYOrig * TmpRowOrg))[TmpXOrig];
            if Assigned(TmpAlphaRotated) then
              TmpAlphaRotated[TmpX] := pByteArray(Integer(TmpAlphaStart)
                + (TmpYOrig * TmpAlphaOrg))[TmpXOrig];
          end else begin
            //Set Transparency
            if Assigned(TmpAlphaRotated) then TmpAlphaRotated[TmpX] := 0;
            TmpRowRotated[TmpX] := TmpTransparent;
          end;
        end else begin
          //Set Transparency
          if Assigned(TmpAlphaRotated) then TmpAlphaRotated[TmpX] := 0;
          TmpRowRotated[TmpX] := TmpTransparent;
        end;
      end;
      Dec(Integer(TmpRowRotated), TmpRowRot);
      if Assigned(TmpAlphaRotated) then Dec(Integer(TmpAlphaRotated), TmpAlphaRot);
    end;
    ARotated.Assign(TmpPng);
  finally
    FreeAndNil(TmpPng);
  end;
end;

Поворачивает довольно быстро, прозрачность сохраняет и все бы хорошо, но на некоторых углах появляется лесенка. Подскажите как можно избавиться от "лесенки"?

Ответить с цитированием
  #2  
Старый 10.03.2015, 13:04
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Применить фильтр гаусса.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 10.03.2015, 17:28
Rusland Rusland вне форума
Прохожий
 
Регистрация: 12.10.2010
Сообщения: 25
Репутация: 10
По умолчанию

А конкретнее? Есть код?
Ответить с цитированием
  #4  
Старый 10.03.2015, 19:05
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Да, код есть, его не может не быть.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #5  
Старый 12.03.2015, 10:22
Rusland Rusland вне форума
Прохожий
 
Регистрация: 12.10.2010
Сообщения: 25
Репутация: 10
По умолчанию

Зачем вообще писать, если нет желания помочь? Набивание постов?
Если есть код, то выложи, если нет, то не надо вообще писать что либо, флудилка в другом месте.
Ответить с цитированием
  #6  
Старый 12.03.2015, 10:53
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
Плохо

Цитата:
Сообщение от Rusland
Зачем вообще писать, если нет желания помочь?
так тебе помогли! ты спросил:
Цитата:
Сообщение от Rusland
Подскажите как можно избавиться от "лесенки"?
тебе ответили:
Цитата:
Сообщение от M.A.D.M.A.N.
Применить фильтр гаусса.

писать за тебя код или искать готовый навряд ли будут.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #7  
Старый 12.03.2015, 11:12
Rusland Rusland вне форума
Прохожий
 
Регистрация: 12.10.2010
Сообщения: 25
Репутация: 10
По умолчанию

Не надо писать за меня, а надо дать ссылок, где уже реализовано это. Раз код есть, то надо его выложить. А иначе на кой форум дался? Или проще в гугль отправлять? Не понимаю я вас ребята.

PS. не забываем, что тут png c прозрачностью

Последний раз редактировалось Rusland, 12.03.2015 в 11:14.
Ответить с цитированием
  #8  
Старый 12.03.2015, 11:30
Rusland Rusland вне форума
Прохожий
 
Регистрация: 12.10.2010
Сообщения: 25
Репутация: 10
По умолчанию

Вот для примера размытие по Гауссу bmp той же самой картинки.

Совершенно не избавляет от лесенки, а просто замыливает всю картинку.

Последний раз редактировалось Rusland, 12.03.2015 в 11:34.
Ответить с цитированием
  #9  
Старый 12.03.2015, 12:57
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

У тебя в коде используются целочисленные значения, потому и лесенка получается.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 08:10.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter