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


Автор: IvanoffAndrey 11.5.2009, 17:03
Здравствуйте.
Может кто знает как увеличивать площадь занимаемую канвой в компоненте TImage?
Вот в Pointe чтобы увеличить площадь доступную для рисования достаточно потянуть за правый нижний уголок и белый листок станет нужных размеров.
Подскажите как это реализуется для Delphi?

Автор: Crw 11.5.2009, 18:58
Цитата(IvanoffAndrey @  11.5.2009,  17:03 Найти цитируемый пост)
Вот в Pointe чтобы увеличить площадь

Как в Pаinte ?
Можно добавить небольшой компонент (типа панельку) в правый нижний угол TImage, сделать эту панельку перетаскиваемой, и при ее перемещении изменять размеры TImage.

Автор: Keeper89 11.5.2009, 19:03
Просто увеличить размер Image (Width и Height) нельзя?

Автор: AntonN 11.5.2009, 23:00
"просто" изменить размеры Timage можно, но толку от этого будет немного.
кроме размеров контрола нужно менять размены "внутренностей" smile
Код

image1.picture.bitmap.width:=image1.width;
image1.picture.bitmap.height:=image1.height;


PS надеюсь я правильно стелепатировал smile

Автор: Alexeis 12.5.2009, 10:26
Можно сделать как в книге Григорьева, то чуток переделать не для дырки, а просто для изменения размеров панели
Код

unit WHMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls;

type
  TFormHole = class(TForm)
    PanelHole: TPanel;
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
  private
    FOldPanelWndProc: TWndMethod;
    procedure PanelWndProc(var Msg: TMessage);
    procedure WMSize(var Msg: TWMSize);message WM_SIZE;
  //  procedure SetRegion;
  end;

var
  FormHole: TFormHole;

implementation

{$R *.DFM}

const
  // Минимальное расстояние от края дырки до края окна.
  HoleDistance = 40;
  // Зона чувствительности рамки панели - насколько пикселей
  // может отстоять курсор вглубь от края панели, чтобы его
  // положение расценивалось как попадание в рамку.
  BorderMouseSensivity = 3;
  // Зона чувствительности угла рамки панели - насколько пикселей
  // может отстоять курсор от угла панели, чтобы его
  // положение расценивалось как попадание в угол рамки.
  CornerMouseSensivity = 15;
  // Толщина рамки дырки, использующаяся при вычислении региона
  HoleBorder = 3;
  // Минимальная ширина и высота дырки
  MinHoleSize = 10;
  // Смещение стрелки относительно соответствующего угла

procedure TFormHole.FormCreate(Sender: TObject);
begin
  FOldPanelWndProc := PanelHole.WindowProc;
  PanelHole.WindowProc := PanelWndProc;
  Image1.Picture.Bitmap.Height := Image1.Height;
  Image1.Picture.Bitmap.Width  := Image1.Width;
end;

procedure TFormHole.PanelWndProc(var Msg: TMessage);
var
  Pt: TPoint;
  R: TRect;
begin
 FOldPanelWndProc(Msg);
 if Msg.Msg = WM_NCHITTEST then
 begin
   Pt := PanelHole.ScreenToClient(Point(Msg.LParamLo, Msg.LParamHi));
   if Pt.X < BorderMouseSensivity then
     Msg.Result := 0
   else if Pt.X >= PanelHole.Width - BorderMouseSensivity then
     if Pt.Y < CornerMouseSensivity then
       Msg.Result := 0
     else if Pt.Y >= PanelHole.Height - CornerMouseSensivity then
       Msg.Result := HTBOTTOMRIGHT
     else
      Msg.Result := HTRIGHT
   else if Pt.Y < BorderMouseSensivity then
      Msg.Result := 0
   else if Pt.Y >= PanelHole.Height - BorderMouseSensivity then
     if Pt.X < CornerMouseSensivity then
       Msg.Result := 0
     else if Pt.X >= PanelHole.Width - CornerMouseSensivity then
       Msg.Result := HTBOTTOMRIGHT
    else
       Msg.Result := HTBOTTOM;
 end
 else if Msg.Msg = WM_SIZE then
 begin
   // Устанавливаем новые ограничения для размеров окна,
   // учитывающие новое положение дырки
   Constraints.MinWidth := Width - ClientWidth + PanelHole.Left + MinHoleSize + HoleDistance;
   Constraints.MinHeight := Height - ClientHeight + PanelHole.Top + MinHoleSize + HoleDistance;
   Image1.Picture.Bitmap.Height := Image1.Height - 1;
   Image1.Picture.Bitmap.Width  := Image1.Width - 1;
   Image1.Invalidate;
   Image1.
 end
 else if Msg.Msg = WM_SIZING then
 begin
   // Копируем переданный прямоугольник в переменную R,
   // одновременно пересчитывая координаты из экранных
   // в клиентские
   R.TopLeft := ScreenToClient(PRect(Msg.LParam)^.TopLeft);
   R.BottomRight := ScreenToClient(PRect(Msg.LParam)^.BottomRight);
   // Если ширина слишком мала, проверяем, за какую
   // сторону тянет пользователь. Если за левую -
   // корректируем координаты левой стороны, если за
   // правую - её координаты
   if R.Right - R.Left < MinHoleSize then
     if Msg.WParam in [WMSZ_BOTTOMLEFT, WMSZ_LEFT, WMSZ_TOPLEFT] then
       R.Left := R.Right - MinHoleSize
     else
       R.Right := R.Left + MinHoleSize;
   // Аналогично действуем, если слишком мала высота
   if R.Bottom - R.Top < MinHoleSize then
     if Msg.WParam in [WMSZ_TOP, WMSZ_TOPLEFT, WMSZ_TOPRIGHT] then
       R.Top := R.Bottom - MinHoleSize
     else
       R.Bottom := R.Top + MinHoleSize;
   // Сдвигаем стороны, слишком близко подошедшие
   // к границам окна
   if R.Left < HoleDistance then
     R.Left := HoleDistance;
   if R.Top < HoleDistance then
     R.Top := HoleDistance;
   if R.Right > ClientWidth - HoleDistance then
     R.Right := ClientWidth - HoleDistance;
   if R.Bottom > ClientHeight - HoleDistance then
     R.Bottom := ClientHeight - HoleDistance;
   // Копируем прямоугольник R, переводя его координаты
   // обратно в экранные
   PRect(Msg.LParam)^.TopLeft := ClientToScreen(R.TopLeft);
   PRect(Msg.LParam)^.BottomRight := ClientToScreen(R.BottomRight);
  end;
end;
 
procedure TFormHole.WMSize(var Msg: TWMSize);
begin
  inherited;
  // При уменьшении размеров окна уменьшаем размер дырки,
  // если границы окна подошли слишком близко к ней
  if PanelHole.Left + PanelHole.Width > ClientWidth - HoleDistance then
    PanelHole.Width := ClientWidth - HoleDistance - PanelHole.Left;
  if PanelHole.Top + PanelHole.Height > ClientHeight - HoleDistance then
    PanelHole.Height := ClientHeight - HoleDistance - PanelHole.Top;
end;

end.


проект в атаче

Автор: IvanoffAndrey 12.5.2009, 16:54
Спасибо всем большое, буду разбираться пока.

Автор: Staruha 22.5.2009, 09:32
Цитата

"просто" изменить размеры Timage можно, но толку от этого будет немного.
кроме размеров контрола нужно менять размены "внутренностей" 

 толк будет,если изменишь свойство Stretch в true. И тяни с помощью отслеживания координат мышки

Автор: AntonN 22.5.2009, 21:31
Staruha, 
костыль. хромированный.

Автор: Staruha 25.5.2009, 07:58
AntonN 
Не поняла. Предлагаю то же что и ты менять размеры smile 

Автор: AntonN 25.5.2009, 13:37
Staruha, не то. Stretch масштабирует исходное изображение до размеров контрола, просто растягивая его. Не трудно предположить, что если исходное изображение будет меньше "контрольного", то нарисованное "как в пейнте" не будет отличаться тонкими прямыми линиями. Более того, если автор рисует "как в пейнте", то уменьшенное исходное изображение может вместить в себя куда меньше информации, нежели бОльшего размера. Проще говоря, на битмапе с шириной 100 пикселей можно нарисовать 5 квадратов по 20 пикселей шириной, а на битмапе в 40 пикселей они будут по 10 пикселей шириной, при растяжении толщина линий будет нефиговой.
PS "комодератор" с такими познаниями? фшоке  smile 

Автор: Alexeis 25.5.2009, 14:01
Цитата(AntonN @  25.5.2009,  12:37 Найти цитируемый пост)
PS "комодератор" с такими познаниями? фшоке

Staruha, комодератор в другом разделе, я например 0 в вижуал бейсике и совсем не знаю как там работает VBA с документами офиса. Ничего удивительного. 

Автор: AntonN 25.5.2009, 14:25
Alexeis, вот уже повозмущацо нельзя smile

Автор: Staruha 25.5.2009, 15:16
 smile Alexeis спасибо что заступился.
AntonN я за простые решения. 
IvanoffAndrey  не сказал для чего ему надо так издеваться над программой
Я так крашу все что под руку попадется.Может ему это надо?
Код

img:=TImage.Create(Form1);
   img.Parent:=panel;
   img.Picture.LoadFromFile('fon5.bmp');
   img.Stretch:=True;
   img.Align:=alClient;

Автор: AntonN 25.5.2009, 16:57
Staruha, но это действительно не решение, просто сохрани в файл битмап и увидишь, что он маленького размера. более того, например чтобы на нем рисовать "как в пейнте" нужно будет постоянно пересчитывать координаты клика (картинка ведь масштабируется) - это никак не путь к простоте smile

Автор: Staruha 26.5.2009, 08:45
Ну, если он будет заниматься реставрацией уже готового изображения,тогда придется масштабировать несомненно.Он же не сказал какую идею он хочет реализовать.А я стем что описываешь сталкивалась(заливаемый объект был крупнее,чем панелька) ,только не знала как это исправить.Теперь знаю  smile 

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