Конференция "Media" » повернуть изображение и сохранить полученное в файл
 
  • alexandr (10.07.11 07:48) [0]
    всем привет.
    Возникла у меня заминка.
    Загружаю изображение, затем поворачиваю его на произвольный угол.
    После этого , нужно сохранить полученное повернутое изображение, при сохранении получаю файл с исходным изображением которое загрузил до начала вращения.

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



    //создаю слой, загружаю в битмап картинку
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    RL:= TRotLayer.Create(ImgView.Layers);
    RL.Bitmap := TBitmap32.Create;
     RL.Bitmap.LoadFromFile('1.bmp');

    with RL.Bitmap do
    begin
    BeginUpdate;
       TLinearResampler.Create(RL.Bitmap);
       TCustomResampler(RL.Bitmap.Resampler).PixelAccessMode := pamTransparentEdge;
      RL.BitmapCenter := FloatPoint(Width / 2, Height / 2);
      MasterAlpha := 200;
       FrameRectS(BoundsRect, $FFFFFFFF);
       DrawMode := dmBlend;
       EndUpdate;
       Changed;

    end;
     RL.Scaled := True;
     RL.Position :=FloatPoint(ImgView.ClientWidth / 2, ImgView.ClientHeight / 2);
    end;

    // вращаю изображение
    procedure TForm1.ScrollBar1Change(Sender: TObject);
    begin
    RL.Angle:=Scrollbar1.Position;
    end;

    //Сохраняю изображение повернутое под некоторый угол
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    RL.Bitmap.SaveToFile('2.bmp');
    end;


  • gvozdkoff (10.07.11 21:41) [1]
    сейчас попробовал повернуть на 90 градусов
    RL.Bitmap.Rotate90;


    далее сохраняю в файл
    RL.Bitmap.SaveToFile('image\temp\1.bmp

    ');

    и что самое интересное , при повороте на 90, 180 и 270 градусов, изображение сохраняется корректно, то есть повернутое на 90, 180 и 270.
    Загадка
  • Омлет © (12.07.11 10:55) [2]
    А где задается угол поворота?
  • Омлет © (12.07.11 11:06) [3]
    Есть подозрение, что TRotLayer только выводит повернутое изображение, а в RL.Bitmap хранит исходное.
  • Омлет © (12.07.11 11:12) [4]
    Ага. Так и есть:


    procedure TCustomAffineLayer.Paint(Buffer: TBitmap32);
    begin
     AdjustTransformation;
     Transform(Buffer, FBitmap, Transformation);
    end;



    В G32 есть другой пример поворота изображения - Examples\Vcl\General\Rotate_Ex - где ясно видно, как использовать Transform.
  • alexandr (12.07.11 14:39) [5]
    Есть подозрение, что TRotLayer только выводит повернутое изображение, а в RL.Bitmap хранит исходное.



    Ого!  я даже  и не думал в эту сторону.
    тот пример смотрел, как то не приглянулся
  • gvozdkoff (12.07.11 15:06) [6]
    Блиин ))) спасибо Вам, огромное.
    Сейчас пробую сохранять под разными углами поворота, получается!! ))
    Вот почему мне не понравился этот пример,
    Вращающийся рисунок вписывается в границы Image, то есть он изменяется в размерах при вращении.
    а TRotLayer вращает изображение с размерами как есть.
    вот как быть?!
  • Омлет © (13.07.11 14:00) [7]
    Просто, масштабировать (Scale) не надо.
  • gvozdkoff (14.07.11 11:25) [8]
    Спасибо. сейчас пробую.
    может я что то не так делаю, вот посмотрите пожалуйста

     в примере Examples\Vcl\General\Rotate_Ex

       
    // calculate a new scale so that the image fits in original boundaries
       Sx := Src.Bitmap.Width / Sx;
       Sy := Src.Bitmap.Height / Sy;
      // scale := Min(Sx, Sy);

      // T.Scale(Scale, Scale);


    либо ставлю масшатб 1

    T.Scale(1, 1);



    но тогда при сохранении появляется ненужный фон.
    пример:
    есть изображение, его высота больше ширины.
    Расположение рисунка вертикальное
    Мы поворачиваем под углом 90 градусов.
    Получаем новое изображение.
    где ширина больше высоты. Изображение располагается горизонтально.
    И видимая область ограничивается.
    Изображение не полностью просматривается.

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

    Много написал всего ), если как то не корректно выразил мысль то поправьте пожалуйста
  • Омлет © (14.07.11 13:21) [9]
    procedure TFormRotateExample.ScaleRot(Alpha: Single);
    var
     SrcR: Integer;
     SrcB: Integer;
     T: TAffineTransformation;
     Sx, Sy, Scale: Single;
    begin
     SrcR := Src.Bitmap.Width - 1;
     SrcB := Src.Bitmap.Height - 1;
     T := TAffineTransformation.Create;
     T.SrcRect := FloatRect(0, 0, SrcR + 1, SrcB + 1);
     try
       T.Clear;
       T.Translate(-SrcR * 0.5, -SrcB * 0.5);
       T.Rotate(0, 0, Alpha);

       Alpha := Alpha * PI / 180;
       Sx := Abs(SrcR * Cos(Alpha)) + Abs(SrcB * Sin(Alpha));
       Sy := Abs(SrcR * Sin(Alpha)) + Abs(SrcB * Cos(Alpha));

       Dst.Bitmap.Width := round(Sx);
       Dst.Bitmap.Height := round(Sy);
       Dst.Width := Dst.Bitmap.Width;
       Dst.Height := Dst.Bitmap.Height;

       T.Translate(Sx * 0.5, Sy * 0.5);

       Dst.BeginUpdate;
       try
         Dst.Bitmap.Clear(clBlack32);
         Transform(Dst.Bitmap, Src.Bitmap, T);
       finally
         Dst.EndUpdate;
       end;
       Dst.Repaint;
     finally
       T.Free;
     end;
    end;

  • gvozdkoff (14.07.11 14:19) [10]
    Вот это вещь !!!!!!
    Ваш пример очень хорош!
    Еще вопрос можно ? Боюсь показаться навязчивым ).
    Я вот все про TRotLayer.
    В
    > Есть подозрение, что TRotLayer только выводит повернутое
    > изображение, а в RL.Bitmap хранит исходное.

    Как же происходит преобразование/поворот ??
    Можно ли отсюда взять картинку при вращении, так как очень уж привлекательная картинка получается при вращении нет лишних  областей при повороте под 45 градусов к примеру, когда рисунок как по диагонали.
  • gvozdkoff (14.07.11 14:21) [11]
    аа, щас вот дошло, если копировать такую картинку , то всеравно ерунда получится
  • Омлет © (14.07.11 14:33) [12]
    Не понял вопрос. Какие такие лишние области при повороте под 45 градусов?
  • gvozdkoff (14.07.11 14:34) [13]
    Вот посмотрите пожалуйста, на данный момент есть задача загрузить изображение(1 слой B.Bitmap), перемещать его, затем вращать (2 слой RL.Bitmap) и снова перемещаем его, но уже повернутое.

    я делаю копию картинки (из 1 слоя) и вставляю ее в слой (2 ) для вращения, затем после вращения в слое 2 я передаю полученное изображение , тут уже варианты,
    1) в исходный 1 слой
    2)1 слой удаляем, делаем новый (3 слой) вставляем в него полученное изображение из 2 слоя, удаляем/очищаем 2 слой.

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

    Что вы думаете об этом ?

    Можно попробовать придумать работать с RL.Bitmap (перемещение, переключение между слоями).
    перемещение активного RL слоя получается, а вот переключение между ними пока хромает
  • gvozdkoff (14.07.11 14:45) [14]

    > Не понял вопрос. Какие такие лишние области при повороте
    > под 45 градусов?

    скриншот ,
    http://85.143.50.133/example.JPG


    получается изображение под углом а вокруг закрашенная область,
    оно вообще думаю так и должно быть.
    Но TRotLayer, хитрая штука, выводит то как красиво ))
  • gvozdkoff (14.07.11 14:57) [15]
    а вот скрин с TRotLayer c комментариями
    http://85.143.50.133/example1.JPG

  • Омлет © (15.07.11 08:21) [16]
    Какая конечная задача? При повороте, естественно, появляется закрашенная область по углам. Это не лишние области. Можно эти области сделать прозрачными и наложить повернутое изображение на другой слой, как в TRotLayer. А при сохранении в bmp, эти области никуда не исчезнут.
  • gvozdkoff (15.07.11 15:56) [17]
    Да , до меня уже дошло что при сохранении эти области остануться ))

    о задаче проекта.
    1.)
    Создать слои в которые подгружается исходное изображение

    B := TBitmapLayer.Create(ImgView.Layers);
    with B do
         try
    Bitmap.LoadFromFile(FileName);


    2.)
    Этот слой можно перемещать, удалять.
    3.)
    Далее  этот слой нужно повернуть, для этого на данный момент использовался TRotLayer.
    4.)  Скопировать повернутое изображение в слой для вращения картинки
    (здесь у меня возникли проблемы с проектом)
    для этого возникло 2 мысли. Ни одна мысль не  была удачной
    - сохранить повернутое изображение в файл и затем подгрузить его в слой который можно вращать

    RL.Bitmap.Savetofile(...); --сохранял так повернутое изображение из TRotLayer;
    Bitmap.LoadFromFile(FileName);

    -затем подгружал в TBitmapLayer для вращения
    - либо , вторая мысль
    B.Bitmap.Assign(RL.Bitmap)


    то есть я копировал битмап и TrotLayer в BitmapLayer

    после поворота нужно снова поработать с перемещением уже повернутого слоя/изображения.
  • Омлет © (18.07.11 10:24) [18]
    Мм.. То, что ты всякими извращенными манипуляциями пытался вращать слой, я понял. А вот конечной цели так и не видно. Что вообще за программа?
 
Конференция "Media" » повернуть изображение и сохранить полученное в файл
Есть новые Нет новых   [134431   +5][b:0][p:0.003]