Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > Вращение PNG


Автор: simsmann 14.9.2008, 16:03
Как вращать PNG компоненты для PNG есть но не в одном не нашел вращения.

Автор: Alexeis 14.9.2008, 16:22
simsmann, PNG->BMP->Вращение->PNG. Нема дураков вращать заархивированую картинку 

Автор: simsmann 14.9.2008, 17:50
Что других вариантов нет. НЕ желательно терять качество.

Автор: BaD_SeCt0R 14.9.2008, 18:14
simsmann, качество при переводе и не теряется. Битмап не имеет сжатия.

Автор: simsmann 14.9.2008, 21:48
А как с прозрачностью при обратной конвертации

Автор: Alexeis 14.9.2008, 22:17
Цитата(simsmann @  14.9.2008,  20:48 Найти цитируемый пост)
А как с прозрачностью при обратной конвертации

  Альфу нужно конвертировать отдельно. Или помещать в альфанал битмапа в формате 32 бита на пиксель smile

Автор: pseud 28.10.2008, 13:03
simsmann, удалось поворочать и не потерять прозрачность?
если да - хотелось бы глянуть на код  smile 

Автор: AntonN 28.10.2008, 20:41

Код

procedure CopyRotateTransparentBrush(_B_in,_B_out: TBitmap; _x,_y,centerX,centerY:integer; trColor:Tcolor; _angle: Double);
const
  MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
type
  PRGBAArray = ^TRGBAArray;
  TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
var cosRadians,_Rad,sinRadians : Double;
  x,y,x_cor,y_cor,x_corS,y_corS,inXOut,inXPr,inXRotated,inYOut,inYPr,inYRotated: Integer;
  RowOut, RowIn: PRGBAArray;
  rc1, bc1, gc1:byte;
  _w,_h:integer;
begin
  _Rad:=_angle; sinRadians:=Sin(_Rad); cosRadians:=Cos(_Rad);
  _w:=_B_in.Width; _h:=_B_in.Height;
  if _x<0 then x_corS:=abs(_x) else x_corS:=0;
  if _y<0 then y_corS:=abs(_y) else y_corS:=0;
  if (_x+_w)>_B_out.Width then x_cor:=_x+_w-_B_out.Width else x_cor:=0;
  if (_y+_h)>_B_out.Height then y_cor:=_y+_h-_B_out.Height else y_cor:=0;
  rc1:=GetRValue(trColor); gc1:=GetGValue(trColor); bc1:=GetBValue(trColor);
  for x:=_h-1-y_cor downto y_corS do begin
    RowIn:=_B_out.Scanline[x+_y]; inXPr:=2*(x-centerY)+1;
    for y:=_w-1-x_cor downto x_corS do begin
      inYPr:=2*(y-centerX)+1;
      inYRotated:=Round(inYPr*CosRadians-inXPr*sinRadians);
      inXRotated:=Round(inYPr*sinRadians+inXPr*cosRadians);
      inYOut:=(inYRotated-1) div 2 + centerX; inXOut:=(inXRotated-1) div 2 + centerY;
      if (inYOut>=0)and(inYOut<=_w-1)and
      (inXOut>=0)and(inXOut<=_h-1) then begin
        RowOut:=_B_in.Scanline[inXOut];
        RowIn[y+_x]:=RowOut[inYOut];
      end;
    end;
  end;
end;


Как пример, оптимизировать еще больше смысла не вижу, проще тогда напряму к данным обращаться в памяти (асм или указатели мучать), для "интерфейсных" операций достаточно, в играх конечно будет подтормаживать.
_x,_y - координаты вывода верхнего левого угла на результирующий битмап, centerX,centerY - центр вращения.
trColor - "прозрачный" цвет, _angle - угол поворота в радианах.

Для повышения качества рекомендую перед поворотом увеличить (просто через canvas.copyrect(), без "качества") исходное изображение (в 2-4 раза) и его повернуть, а потом уменьшить обратно уже повернутое.

Автор: pseud 29.10.2008, 13:49
trColor - концы не найдены
кроме пустой инициализации:
Код

rc1:=GetRValue(trColor); gc1:=GetGValue(trColor); bc1:=GetBValue(trColor);


прозрачность - имеется ввиду не полная прозрачность одного цвета, а альфа-канал - прозрачность любого пиксела причем любой "силы"

Автор: AntonN 29.10.2008, 15:07
а, ну да, я его почикал для альфы полной, он до этого просто с transparent_color вращал, забыл удалить параметр smile
ну а код вращает с альфой, если что...

Автор: pseud 29.10.2008, 16:27
что-то ты переоптимизировал или я руки не доточил.
малевич - белый квадрат.

Автор: AntonN 29.10.2008, 16:46
наверное руки.
битмапы должны быть 32 битные.

Автор: pseud 29.10.2008, 17:07
ушел за точилкой

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)