Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.01.2015, 16:27   #1
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию Быстрое отражение изображения

Есть ли какие быстрые способы в делфи отразить по вертикали, горизонтали, перевернуть изображение на 90, 180 градусов, кроме как попиксельная перерисовка?
NIKOLAYY2 вне форума Ответить с цитированием
Старый 22.01.2015, 16:35   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Есть конечно. Работа с канвой в памяти, а только потом ее отрисовка.
Или есть еще двойная буфферизация. кажется компонент Image этим обладает. Изображение на момент изменения блокируется вызовом спецметодов (не помню их название, что-то типа BeginUpdate), меняется без перерисовки, после чего блок снимается и рисунок выводится на экран уже измененным. Что правда тут я могу путать, ибо с Делфи не работал давненько, и по большему для такого использую отдельный объект TCanvas.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 22.01.2015, 21:47   #3
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,876
По умолчанию

Флип по осям - тут
Поворот на 180 - тоже самое, что одновременный флип и по горизонтали и по вертикали.

Поворот на 90 не подскажу..
TBitmap.ScanLine вестимо, но Вам, я понял, попиксельно не хотелось... Ну этот способ быстрый, если что.

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

Ну и, понятное дело, всегда есть варианты с огл/дх.
phomm вне форума Ответить с цитированием
Старый 24.01.2015, 04:47   #4
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию

phomm
Так и непонял куда в коде вставлять Image, я хотел с Image1 в Image2 отобразить в перевернутом положении, но не отобразилось ни как.
NIKOLAYY2 вне форума Ответить с цитированием
Старый 24.01.2015, 15:17   #5
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,876
По умолчанию

Имхо, от имеджей надо отказываться полностью.
Лучше брать сразу буферный битмап (обычно размером с экран/клиентскую_часть_формы), и на него врисовывать по нужным координатам битмапы всех объектов ( обычно стоит завести некую структуру из битмапа, координат и прочих свойств объектов), и так каждый такт игры (хотя, конечно, есть более экономичные средства, но пока не об экономии речь), полностью нарисованную картинку в буфбитмапе единожды рисовать на форму через канвас. Ранее в этой же цепочке действий должен находиться обработчик игрового такта - изменение свойств всех объектов, в т.ч. координат.
Все эти принципы, опять же, давно разжёваны, Вы бы потрудились изучить учебные темы в разделе создания игр.

А по теме - функция, которую я привёл - как раз и работает с битмапами, и для описанного способа она вполне неплоха, для имейджей же придётся делать пачку телодвижений - создавать битмап, копировать картинку из имейджа в созданный битмап, кидать его в функцию, и после флипа снова записывать в имейдж. Правда, я не могу сказать с гарантией, что не будет срабатывать подход в лоб: Flip(True, True, MyImage1.Picture.Bitmap), я только подозреваю, что не будет, почему и говорю, что нужны телодвижения.

Последний раз редактировалось phomm; 24.01.2015 в 15:21.
phomm вне форума Ответить с цитированием
Старый 25.01.2015, 02:11   #6
kropotkina-alice
Форумчанин
 
Аватар для kropotkina-alice
 
Регистрация: 27.10.2014
Сообщений: 594
По умолчанию

Цитата:
Сообщение от NIKOLAYY2 Посмотреть сообщение
Есть ли какие быстрые способы в делфи отразить по вертикали, горизонтали, перевернуть изображение на 90, 180 градусов, кроме как попиксельная перерисовка?
Нате вам простенькую процедурку для отражения без сложных извращений:
Код:
procedure TForm1.FlipBitmap(bmap: TBitmap; FlipHor: Boolean);
var
  x, y, W, H: Integer;
  Pixel_1, Pixel_2: PRGBTriple;
  MemPixel: TRGBTriple;
begin
  bmap.PixelFormat := pf24Bit;
  W := bmap.Width - 1;
  H := bmap.Height - 1;
  if FlipHor then
    for y := 0 to H do
    begin
       Pixel_1 := bmap.ScanLine[y];
      Pixel_2 := bmap.ScanLine[y];
       Inc(Pixel_2, W);
       for x := 0 to W div 2 do
      begin
         MemPixel := Pixel_1^;
        Pixel_1^ := Pixel_2^;
        Pixel_2^ := MemPixel;
        Inc(Pixel_1); 
        Dec(Pixel_2); 
      end;
    end  else
    for y := 0 to H div 2 do
    begin
      Pixel_1 := bmap.ScanLine[y];
      Pixel_2 := bmap.ScanLine[H - y];
      for x := 0 to W do
      begin
         MemPixel := Pixel_1^;
        Pixel_1^ := Pixel_2^;
        Pixel_2^ := MemPixel;
        Inc(Pixel_1);
        Inc(Pixel_2); 
      end;
    end;
end;

Вызов делается так:

procedure TForm1.Button1Click(Sender: TObject);
begin
FlipBitmap(Image1.Picture.Bitmap,False); //отражение по вертикали
Image1.Repaint;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
FlipBitmap(Image1.Picture.Bitmap,True); //отражение по горизонтали
Image1.Repaint;
end;
kropotkina-alice вне форума Ответить с цитированием
Старый 25.01.2015, 14:23   #7
NIKOLAYY2
Форумчанин
 
Регистрация: 23.12.2014
Сообщений: 220
По умолчанию

Вот еще нашел хороший способ:

Код:
var
 a: TBitmap;
 x, y: integer;
 SrcRect, DstRect: TRect;
begin
 if OpenDialog1.Execute = false then
 Exit;
 a := TBitmap.Create;
 a.LoadFromFile(OpenDialog1.FileName);

 X := a.Width;
 Y := a.Height;
 SrcRect := Rect(0, 0, X, Y);
 DstRect := Rect(X, 0, 0, Y);
 form1.Canvas.CopyRect(DstRect, a.Canvas, SrcRect);
 a.Free;
end;
Проверял и оказалось канву можно везде копировать в любом направлении где есть область Rect! Даже где ее и нету ее можно вставить везде где только можно!
Тут главное с какой по какую координату определить, и переуказать если изображение не квадратное и мы поворачиваем на 90 градусов свойства-
Width;
Height;
вторичного прямоугольника.

Последний раз редактировалось NIKOLAYY2; 25.01.2015 в 14:26.
NIKOLAYY2 вне форума Ответить с цитированием
Старый 08.10.2016, 10:39   #8
KukoBoy
Новичок
Джуниор
 
Регистрация: 08.10.2016
Сообщений: 1
По умолчанию Последняя процедура отражения

Код:
unit lab3;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, jpeg;

type
  TForm1 = class(TForm)
    Image1:  TImage;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    OpenDialog1: TOpenDialog;
    procedure Button5Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


var Form1: TForm1;

implementation

{$R *.dfm}

{Процедура перевода в чёрно белый спектр}
procedure TForm1.Button1Click(Sender: TObject);
var x,y,r,g,b:integer;
begin
  for x := 0 to Image1.Width do
    for y := 0 to Image1.Height do
    begin
      r:=getRvalue(Image1.Canvas.Pixels[x,y]);
      g:=getGvalue(Image1.Canvas.Pixels[x,y]);
      b:=getBvalue(Image1.Canvas.Pixels[x,y]);

      Image1.Canvas.Pixels[x,y]:=RGB(round(r*0.3),round(g*0.59),round(b*0.11));
    end;

end;

{Процедура перевода с зелёным оттенком}
procedure TForm1.Button2Click(Sender: TObject);
var x,y,r,g,b:integer;
begin
    for x := 0 to Image1.ClientWidth do
      for y := 0 to Image1.ClientHeight do
      begin
        r:=getRvalue(Image1.Canvas.Pixels[x,y]);
        g:=getGvalue(Image1.Canvas.Pixels[x,y]);
        b:=getBvalue(Image1.Canvas.Pixels[x,y]);

        Image1.Canvas.Pixels[x,y]:=RGB(round(r*0.9),g,round(b*0.9));
      end;
end;

{Процедура перевода в негатив}
procedure TForm1.Button3Click(Sender: TObject);
var x,y,r,g,b:integer;
begin
  for x := 0 to Image1.Width do
    for y := 0 to Image1.Height do
    begin
      r:=getRvalue(Image1.Canvas.Pixels[x,y]);
      g:=getGvalue(Image1.Canvas.Pixels[x,y]);
      b:=getBvalue(Image1.Canvas.Pixels[x,y]);

      Image1.Canvas.Pixels[x,y]:=RGB(round(255-r),round(255-g),round(255-b));
    end;

end;

{Процедура отражения}
procedure TForm1.Button4Click(Sender: TObject);
var i,j,r,g,b,r1,g1,b1:integer;
begin
  for i:= 1 to Image1.Width do
    for j:= 1 to Image1.Height do
    begin
      r:=GetRvalue(Image1.Canvas.Pixels[i,j]);
      g:=GetGvalue(Image1.Canvas.Pixels[i,j]);
      b:=GetBvalue(Image1.Canvas.Pixels[i,j]);

      r1:=GetRvalue(Image1.Canvas.Pixels[i,j]);
      g1:=GetGvalue(Image1.Canvas.Pixels[i,j]);
      b1:=GetBvalue(Image1.Canvas.Pixels[i,j]);

Image1.Canvas.Pixels[i,j]:=Image1.Canvas.Pixels[Image1.Height-i,j];
    end;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  Image1.Picture.LoadFromFile(OpenDialog1.FileName);
end;

end.

Последний раз редактировалось Arigato; 12.10.2016 в 13:20.
KukoBoy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Зеркальное отражение изображения Neketek Общие вопросы по Java, Java SE, Kotlin 1 06.05.2013 15:02
Отражение данных с термодатчиков SokolGL Фриланс 5 14.03.2012 11:46
Зеркальное отражение V@mpir Общие вопросы Delphi 3 15.09.2009 22:27
Отражение луча Illusionist Общие вопросы Delphi 3 30.05.2009 23:20
Отражение рисунка от стенок Надежда.. Мультимедиа в Delphi 14 20.12.2008 23:24