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


Автор: Vladimir_K 31.12.2006, 21:45
Вывожу на PaintBox график большой протяженности, но, как оказалось, максимальное значение Width=32767. С этим можно что-либо сделать ( в смысле увеличить...)?

Автор: Alexeis 31.12.2006, 23:56
Цитата(Vladimir_K @  31.12.2006,  21:45 Найти цитируемый пост)
С этим можно что-либо сделать ( в смысле увеличить...)? 

 smile что увеличить? Монитор? smile 

Автор: Stalker Ghost 1.1.2007, 04:48
А как выводишь? С какого нибудь массива или матрици?

Автор: Alexeis 1.1.2007, 12:06
А кажется я вспомнил, здесь речь не области вывода, а о размере битмапа, точнее об ограничениях на ширину битмапа. 
  Есть еще такая идея, попробовать загружать его на winapi про помощи loadImage а рисовать при помощи bitblt. У этих функций ограничения должны быть по больше.

Автор: Vladimir_K 1.1.2007, 19:48
Сделал просто: на форме расположил ScrollBox, внутри которого - PaintBox. Для PaintBox задаю Width=32767, на ScrollBox гор. прокруткой можно просмотреть всю длину PaintBox'а, и вывожу для проверки прямоугольник (или линию). Так вот, при Width<=32767 рисовать на канве PaintBox'а можно, если > 32767 - нельзя. Видимо для Width макс. значение = SmallInt. Можно ли изменить его на LongInt?

Автор: Vladimir_K 1.1.2007, 23:15
Для PaintBox задал Width>50000, так вот в Windows'98 мой график не отображается, а в XP (установил на этот же комп, на котором пишу прогу) - все работает нормально. Проверял на другом компе с Windows'XP - график не отображается (пока не уменьшу Width<32768).
Как такое возможно?

Автор: Alexeis 2.1.2007, 01:48
Vladimir_K, конечно возможно. Windows'XP построен на ядре NT отличном от 98.  smile ... я даже не предполагал, что это ограничение DC, а не делфи. Вообще, задача не стандартная, потому рекомендую использовать нестандартный подход. Например, использовать TScrollBar ведь по вертикали скрол не нужен. По положению движка определить часть картинки, которую нужно отрисовать - расплюнуть. Это же простая арифметика. Просто рисовать ее при помощи copyrect или ее виндового аналога (если битмап отказывается грузить такую картинку). Кстати с битмапом ассоциируется DC, возможно как раз в 98 DC не признает координаты большее чем 32767, потому что битмап, что паинтбокс не смогут такое отображать, ведь они оба используют DC. Вообще, на 98 уже мало ориентируются, лучше проверять совместимость с 2000 виндой. 
  Лично я бы разобрал бы картинку вручную и написал бы свой CopyRect следующим образом: данные из исходного битмапа (образа файла в памяти), записывал бы TBitmap, размером в видимую часть паинтбокса, прямым обращением к его карте, а затем сам битмап одним махом выводил бы на паинтбокс.

Автор: Vladimir_K 2.1.2007, 08:36
Цитата(Alexeis @  2.1.2007,  01:48 Найти цитируемый пост)
Например, использовать TScrollBar ведь по вертикали скрол не нужен. По положению движка определить часть картинки, которую нужно отрисовать - расплюнуть.

Я так и делаю: PaintBox, например шириной 20000, а ScrollBox = 500, определяю х-координату левой видимой части PaintBox, и вывожу ту часть графика (рисунка), которая в данный момент видна (шириной 500). При горизонтальном скроллировании все повторяется. Если при скроле выводить сразу все изображение на PaintBox - сильно мерцает изображение и медленно идет гор. скрол.

Цитата(Alexeis @  2.1.2007,  01:48 Найти цитируемый пост)
Лично я бы разобрал бы картинку вручную и написал бы свой CopyRect следующим образом: данные из исходного битмапа (образа файла в памяти), записывал бы TBitmap, размером в видимую часть паинтбокса, прямым обращением к его карте, а затем сам битмап одним махом выводил бы на паинтбокс. 

Круто... Для меня это немного сложновато - Delphi я еще только изучаю.
Как бы мне про это поподробнее узнать?

Автор: Alexeis 2.1.2007, 13:58
Попробую написать, что-то подобное. Кстати в win2000 и открывается и рисуются такие битмапы нормально.

Автор: Alexeis 2.1.2007, 15:03
вот получилось
Код

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    btn1: TButton;
    tmr1: TTimer;
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure tmr1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{$O-}

type
  TColorArray = packed array[0..High(integer) div 4 - 1] of integer;
  PColorArray = ^TColorArray;

var
  b   : TBitmap;
  l   : integer;
  h, w: integer;
  size: Integer;
  map : array of PColorArray;
  mem : Pointer;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeMem(mem, size);
  b.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  FH  : TBitmapFileHeader;
  IH  : TBitmapInfoHeader;
  f   : TFileStream;
  i   : integer;

begin
  b := TBitmap.Create;
  b.PixelFormat := pf24bit;

  f   := TFileStream.Create('f:/1.bmp', fmOpenRead);
  f.ReadBuffer(FH, sizeof(FH));
  f.ReadBuffer(IH, sizeof(IH));

  w := IH.biWidth;
  h := IH.biHeight;

  b.Width  := 250;
  b.Height := h;

  l := ((w * 3 + 3) div 4) * 4;
  size := l * h;
  GetMem(mem, size);
  f.Position := FH.bfOffBits;
  f.ReadBuffer(mem^, size);

  SetLength(map, IH.biHeight);
  map[0] := mem;
  for i := 1 to h  - 1
  do
    map[i] := Pointer(Integer(map[i-1]) + l);

  f.Free;
end;


Procedure CopyRect(r : TRect; cv : TCanvas);
var
  i, j         : Integer;
  start, count : Integer;
  sline, fline : Integer;
Begin
  start := max(0, r.Left * 3);
  count := max(r.Right * 3 - start, 0);
  sline := max(r.Top, 0);
  fline := min(r.Bottom, h - 1);
  for i := sline to fline
  do
    Move(pointer(integer(map[i]) + start)^, b.ScanLine[i]^, count);

  Cv.Draw(20, 20, b);
end;

var
  st : integer = 0;

procedure TForm1.tmr1Timer(Sender: TObject);
begin
  CopyRect(rect(st, 0, st + 249, 99), Canvas);
  st := st + 249;
end;

end.

Автор: Vladimir_K 2.1.2007, 20:54
Вот спасибо. Буду разбираться!

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