|
#1
|
|||
|
|||
Вращение 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
|
||||
|
||||
Применить фильтр гаусса.
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#3
|
|||
|
|||
А конкретнее? Есть код?
|
#4
|
||||
|
||||
Да, код есть, его не может не быть.
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |
#5
|
|||
|
|||
Зачем вообще писать, если нет желания помочь? Набивание постов?
Если есть код, то выложи, если нет, то не надо вообще писать что либо, флудилка в другом месте. |
#6
|
||||
|
||||
Цитата:
Цитата:
Цитата:
писать за тебя код или искать готовый навряд ли будут. Пишу программы за еду. __________________ |
#7
|
|||
|
|||
Не надо писать за меня, а надо дать ссылок, где уже реализовано это. Раз код есть, то надо его выложить. А иначе на кой форум дался? Или проще в гугль отправлять? Не понимаю я вас ребята.
PS. не забываем, что тут png c прозрачностью Последний раз редактировалось Rusland, 12.03.2015 в 11:14. |
#8
|
|||
|
|||
Вот для примера размытие по Гауссу bmp той же самой картинки.
Совершенно не избавляет от лесенки, а просто замыливает всю картинку. Последний раз редактировалось Rusland, 12.03.2015 в 11:34. |
#9
|
||||
|
||||
У тебя в коде используются целочисленные значения, потому и лесенка получается.
— Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию |