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


Автор: furious 28.10.2009, 22:13
Вобщем есть задача сделать граф. редактор, типа паинта, пока получилось только так:
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Menus, ExtDlgs, StdCtrls, Buttons, Spin, ColorGrd;

type
  TForm1 = class(TForm)

    ScrollBox1: TScrollBox;
    PaintBox1: TPaintBox;
    OpenPictureDialog1: TOpenPictureDialog;
    SavePictureDialog1: TSavePictureDialog;
    MainMenu1: TMainMenu;
    N1: TMenuItem;
    N5: TMenuItem;
    N6: TMenuItem;
    N7: TMenuItem;
    N8: TMenuItem;
    N9: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    ColorDialog1: TColorDialog;
    PrintDialog1: TPrintDialog;
    N10: TMenuItem;
    Panel1: TPanel;
    SpeedButton1: TSpeedButton;
    SpeedButton4: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    N11: TMenuItem;
    f1: TMenuItem;
    SpinEdit1: TSpinEdit;
    N4: TMenuItem;
    N12: TMenuItem;
    ColorGrid1: TColorGrid;
    SpeedButton5: TSpeedButton;
    ControlBar1: TControlBar;
    procedure  PaintBox1MouseDown(Sender:TObject; Button: TMouseButton;
    Shift:TShiftState; x,y:Integer);
    procedure  PaintBox1MouseUp(Sender:TObject; Button: TMouseButton;
Shift:TShiftState; x,y:Integer);
    procedure N9Click(Sender: TObject);
    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure N10Click(Sender: TObject);
    procedure N11Click(Sender: TObject);
    procedure f1Click(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);
    procedure N12Click(Sender: TObject);
    procedure ColorGrid1Change(Sender: TObject);







  private
    { Private declarations }
  public
    { Public declarations }

  end;

var
  Form1: TForm1;
  drag:boolean;
  Start: TPoint;
  a:integer;

implementation

{$R *.dfm}



procedure  TForm1.PaintBox1MouseUp(Sender:TObject; Button: TMouseButton;
Shift:TShiftState; x,y:Integer);
begin

drag:=false;
end;

procedure TForm1.PaintBox1MouseDown(Sender:TObject; Button: TMouseButton;
Shift:TShiftState; x,y:Integer);
begin
Start.X:=X;
Start.Y:=Y;
drag:=true;

end;



procedure TForm1.N9Click(Sender: TObject);
begin
Form1.Close;
end;

procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer );
begin
 

 if speedbutton1.Down then
 begin
   if drag=true then
   begin
      
      paintbox1.Canvas.Pen.Width:=1;
      paintbox1.Canvas.LineTo(x,y);
   end;
   if drag=false then
   begin
     paintbox1.Canvas.MoveTo(x,y);
   end;
  end;

  if speedbutton2.Down then
  begin
    if drag=true then
       begin
       a:=spinedit1.Value;
       paintbox1.Canvas.Pen.Width:=a;

       PaintBox1.Canvas.Rectangle(x,y,x+n,y+n);

       end;
    end;
   if speedbutton3.Down then
   begin
     if drag=true then
      begin
      a:=spinedit1.Value;
      paintbox1.Canvas.Pen.Width:=a;
      paintbox1.Canvas.Ellipse(start.X,start.Y,x,y);

      end;
   end;
   if speedbutton4.Down then
   begin
     if drag=true then
   begin
      a:=spinedit1.Value;
      paintbox1.Canvas.Pen.Width:=a;
      paintbox1.Canvas.LineTo(x,y);
   end;
   if drag=false then
   begin
     paintbox1.Canvas.MoveTo(x,y);
   end;
   end;
   if speedbutton5.Down then
    begin
     if drag=true then
      begin
      paintbox1.Canvas.MoveTo(start.X,start.Y);
      paintbox1.Canvas.LineTo(x,y);
      end;

    end;
end;




procedure TForm1.N10Click(Sender: TObject);
begin
paintbox1.Canvas.Pen.Width:=0;
paintbox1.Repaint;
paintbox1.Canvas.Rectangle(0,0,width,height);
end;



procedure TForm1.N11Click(Sender: TObject);
begin
panel1.Visible:=false;
  if panel1.Visible=false then

  begin
   n11.Checked:=false;
   end
   else
   begin
   n11.Checked:=true;
   end ;
  if panel1.Visible=false then

end;

procedure TForm1.f1Click(Sender: TObject);
begin
 panel1.Visible:=false or true
end;



procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
if spinedit1.Value<0 then
 begin
 spinedit1.Value:=0;
 MessageDlg('Are you noob?',mtConfirmation,[mbYes],0);
 end;
if speedbutton1.Down=true then
 begin
 spinedit1.Value:=1;
 end;

end;



procedure TForm1.N12Click(Sender: TObject);
begin
colordialog1.Execute;
paintbox1.Canvas.Pen.Color:=colordialog1.Color;
end;



procedure TForm1.ColorGrid1Change(Sender: TObject);
begin
paintbox1.Canvas.pen.Color:=ColorGrid1.ForeGroundColor;
colordialog1.Color:=ColorGrid1.ForeGroundColor;;
end;



end.

Вопрос: как сделать чтоб фигуры рисовались нормально?


Автор: Alexeis 28.10.2009, 23:11
Что значит нормально?

Автор: furious 28.10.2009, 23:20
ну там типа следы остаются после увеличения/уменьшения фигуры


дописал вот так

      paintbox1.refresh;
      a:=spinedit1.Value;
      paintbox1.Canvas.Pen.Width:=a;
      paintbox1.Canvas.Ellipse(start.X,start.Y,x,y);

ток потом если нарисовать еще  один круг, то предыдущий стирается

я в панике  smile 

Автор: Alexeis 28.10.2009, 23:36
  Так нужно стирать все и рисовать заново при каждом изменении.

Автор: furious 28.10.2009, 23:38
дописал вот так

      paintbox1.refresh;
      a:=spinedit1.Value;
      paintbox1.Canvas.Pen.Width:=a;
      paintbox1.Canvas.Ellipse(start.X,start.Y,x,y);

только потом если нарисовать еще  один круг, то предыдущий стирается

Автор: Alexeis 28.10.2009, 23:42
Цитата(furious @  28.10.2009,  22:38 Найти цитируемый пост)
только потом если нарисовать еще  один круг, то предыдущий стирается 

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

Автор: furious 28.10.2009, 23:43
а можно это в виде кода, потому что я мало что понял - нубас (

Автор: Alexeis 28.10.2009, 23:49
Класс TBitmap умеет хранить картинку. Каждый новый кадр, рисуется так. Сначала на канву рисуется содержимое TBitmap затем новый примитив. Когда примитив закончили рисовать, его повторно рисуют, но уже на битмап, так чтобы в следующий раз его можно было восстановить нарисовав битмап на канве.
  
Цитата(furious @  28.10.2009,  22:43 Найти цитируемый пост)
а можно это в виде кода

Спать хоцца  smile . Время позднее.

Автор: furious 28.10.2009, 23:53
ну напишите плиз когда сможете, я то попробуй, но не думаю что что-то из этого выйдет

Автор: Alexeis 29.10.2009, 11:19
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Buttons, StdCtrls, Spin;

type
  TForm1 = class(TForm)
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    PaintBox1: TPaintBox;
    SpeedButton5: TSpeedButton;
    SpinEdit1: TSpinEdit;
    procedure  PaintBox1MouseDown(Sender:TObject; Button: TMouseButton;
    Shift:TShiftState; x,y:Integer);
    procedure  PaintBox1MouseUp(Sender:TObject; Button: TMouseButton;
Shift:TShiftState; x,y:Integer);
    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormResize(Sender: TObject);
    procedure DrawImg(Canvas : TCanvas; X, Y: Integer);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
  //  procedure ERACEBKG(msg : ) message WM_ERASEBKG;
  private
    { Private declarations }
  public
    { Public declarations }
    BackImage : TBitmap;
  end;

var
  Form1 : TForm1;
  drag  : boolean;
  Start : TPoint;
  a     : integer;

implementation

{$R *.dfm}

procedure  TForm1.PaintBox1MouseUp(Sender:TObject; Button: TMouseButton;
Shift:TShiftState; x,y:Integer);
begin
  DrawImg(BackImage.Canvas, x, y);
  PaintBox1.Canvas.Draw(0, 0, BackImage);
  drag := false;
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  PaintBox1.Canvas.Draw(0, 0, BackImage);
end;

procedure TForm1.DrawImg(Canvas: TCanvas; X, Y: Integer);
begin
 PaintBox1.Canvas.Brush.Color := clWhite;
 if speedbutton1.Down then
 begin
   if drag=true then
   begin
      Canvas.Pen.Width:=1;
      Canvas.LineTo(x,y);
   end;
   if drag=false then
   begin
     Canvas.MoveTo(x,y);
   end;
  end;
  if speedbutton2.Down then
  begin
    if drag=true then
       begin
         a:=spinedit1.Value;
         Canvas.Pen.Width:=a;
   //    PaintBox1.Canvas.Rectangle(x,y,x+n,y+n);
       end;
    end;
   if speedbutton3.Down then
   begin
     if drag=true then
      begin
        a:=spinedit1.Value;
        Canvas.Pen.Width := a;
        Canvas.Ellipse(start.X, start.Y, x,y);
      end;
   end;
   if speedbutton4.Down then
   begin
     if drag=true then
   begin
      a:=spinedit1.Value;
      Canvas.Pen.Width:=a;
      Canvas.LineTo(x,y);
   end;
   if drag=false then
   begin
     paintbox1.Canvas.MoveTo(x,y);
   end;
   end;
   if speedbutton5.Down then
    begin
     if drag=true then
      begin
        Canvas.MoveTo(start.X,start.Y);
        Canvas.LineTo(x,y);
      end;
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  BackImage := TBitmap.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  BackImage.Free;
end;

procedure TForm1.FormResize(Sender: TObject);
var
  tmp : TBitmap;
begin
  tmp := TBitmap.Create;
  tmp.SetSize(ClientWidth, ClientHeight);
  tmp.Canvas.Draw(0, 0, BackImage);

  BackImage.Free;
  BackImage := tmp;
end;

procedure TForm1.PaintBox1MouseDown(Sender:TObject; Button: TMouseButton;
Shift:TShiftState; x,y:Integer);
begin
  Start.X:=X;
  Start.Y:=Y;
  drag:=true;
end;

procedure TForm1.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer );
begin
   PaintBox1.Canvas.Draw(0, 0, BackImage);
   DrawImg(PaintBox1.Canvas, x, y);
end;


end.


Автор: furious 29.10.2009, 13:10
undeclared identifier: "SetSize"

Автор: Alexeis 29.10.2009, 13:20
Думаю невелика проблема поправить smile .

Добавлено через 35 секунд
  Этого метода нет в старых версиях Delphi 7 и ниже...

Автор: furious 29.10.2009, 13:34
а как поправит-то?

delphi 7
как версия хз
можно как-нибудь без этого? и за что setsize отвечает ?

Автор: Alexeis 29.10.2009, 13:51
Цитата(furious @  29.10.2009,  12:34 Найти цитируемый пост)
можно как-нибудь без этого? и за что setsize отвечает ?

  Наверное она делает, что-то невероятно заумное и сложное, но никак не меняет ширину и высоту Битмапа. 

Автор: furious 29.10.2009, 14:05
 smile 
кароче как было так все и осталось  smile 

Автор: Alexeis 29.10.2009, 14:37
Предлагаю глянуть на проект целиком. Там есть и экзешник.

Автор: furious 29.10.2009, 15:20
спс, но уже начал делать немного по-другому, пока получается.
а как сделать кнопки такие как в вашем проекте?

Автор: Alexeis 29.10.2009, 15:24
Цитата(furious @  29.10.2009,  14:20 Найти цитируемый пост)
а как сделать кнопки такие как в вашем проекте? 

  Это ХР манифест. В Delphi7 он в Additional, а в новых версиях включен автоматически.

Цитата(furious @  29.10.2009,  14:20 Найти цитируемый пост)
спс, но уже начал делать немного по-другому, пока получается.

  Как по-другому ?

Автор: furious 29.10.2009, 15:32
http://forum.vingrad.ru/forum/topic-273930/anchor-entry2007674/0.html

Автор: furious 29.10.2009, 15:59
и опять   smile 
не могу сделать чтоб можно было рисовать карандашом, прямоугольник и круг(три разные кнопки)  smile 

Автор: furious 29.10.2009, 16:35
прямоугольник и круг сделал, а карандаш помогите плиз 

help me please smile 

Автор: furious 29.10.2009, 21:20
все сделал, осталось сделать все красивеньким smile
Alexeis спс за помощь 

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