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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 22.07.2010, 09:34   #1
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию Canvas + Zoom - не работает.

Код:
procedure TFRMMain.FormCreate(Sender: TObject);
Var
 X,Y : Integer;
begin
 FRMMain.Left := 100;
 FRMMain.Top := 0;
 Bit := TBitMap.Create;
 Bit.Width := 50;
 Bit.Height := 50;
 BitZ := TBitMap.Create;
 BitZ.Width := 50;
 BitZ.Height := 50;
 If ParamStr(1) = '' Then
  Begin
   For Y := 0 To 499 Do
    For X := 0 To 499 Do
     Bit.Canvas.Pixels[X,Y] := $000000;
   Bit.Canvas.Pixels[0,0] := $0000FF;
   BitZ.Canvas.Draw(0,0, Bit);
  End
 Else
  Begin
   {...}
  End;
 FRMMain.IMGMain.Width := 50;
 FRMMain.IMGMain.Height := 50;
 FRMMain.IMGMain.Canvas.Draw(0,0,BitZ);
end;
Код:
procedure TFRMMain.RG2Click(Sender: TObject);
Begin
 Zoom := Round(Exp(FRMMain.RG2.ItemIndex * Ln(2)));
 DrawBit;
End;
Код:
Procedure DrawBit;
Var
 X,Y : Integer;
Begin
 BitZ.Width  := Bit.Width  * Zoom;
 BitZ.Height := Bit.Height * Zoom;
 For Y := 0 To BitZ.Height - 1 Do
  For X := 0 To BitZ.Widht - 1 Do
   Begin
    BitZ.Canvas.Pixels[X,Y] := Bit.Canvas.Pixels[X Div Zoom, Y Div Zoom];
   End;
 FRMMain.IMGMain.Width  := BitZ.Width;
 FRMMain.IMGMain.Height := BitZ.Height;
 FRMMain.IMGMain.Canvas.Draw(0,0, BitZ);
 FRMMain.IMGMain.Refresh;
End;
Не пашет и все тут. Выражается так - пиксель, который я установил красным в OnCreate увеличивается, а вот вся картинка (черный квадрат) остается прежних размеров. Причем IMAGE увеличивает размеры- скроллбокс дает прокрутки.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ

Последний раз редактировалось Alex Cones; 22.07.2010 в 09:38.
Alex Cones вне форума Ответить с цитированием
Старый 22.07.2010, 09:52   #2
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Сделал другой вариант, та же проблема:
Код:
Procedure DrawBit;
Var
 mRect : TRect;
Begin
 mRect := Rect(0, 0, Bit.Width * Zoom, Bit.Height * Zoom);
 FRMMain.IMGMain.Width := Bit.Width * Zoom;
 FRMMain.IMGMain.Height := Bit.Height * Zoom;
 FRMMain.IMGMain.Canvas.StretchDraw(mRect, Bit);
End;

procedure TFRMMain.FormCreate(Sender: TObject);
Var
 X,Y : Integer;
begin
 FRMMain.Left := 100;
 FRMMain.Top := 0;
 Bit := TBitMap.Create;
 Bit.Width := 50;
 Bit.Height := 50;
 If ParamStr(1) = '' Then
  Begin
   For Y := 0 To 49 Do
    For X := 0 To 49 Do
     Bit.Canvas.Pixels[X,Y] := $000000;
   Bit.Canvas.Pixels[0,0] := $0000FF;
  End
 Else
  Begin
   {...}
  End;
 FRMMain.IMGMain.Width := 50;
 FRMMain.IMGMain.Height := 50;
 FRMMain.IMGMain.Canvas.Draw(0,0,Bit);
end;

procedure TFRMMain.FormDestroy(Sender: TObject);
begin
 Bit.Free;
end;
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 22.07.2010, 10:25   #3
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Первое чтобы я сделал, это поменял бы Image на PaintBox. Высокоуровневость Image часто только мешает и выражается в подобных багах, и в потере времени на их поиск. PaintBox же простой как три копейки, и делает только то что ты ему говоришь, добавить только процедуру его обновления (PaintBox.OnPaint) чтобы не пропадал когда не надо, но рисовать нужно непосредственно в нем, а не через обновление, а то мерцать будет, обновление пусть вызывается только системой.

Второе что я заметил, это заливка белым цветом в цикле, очень неэффективно. Делай просто FillRect(ClientRect), будет на порядок быстрее.

Я так понял, пытаешься масштабирование замутить? Для квадратиков конечно и так сойдет, но для более сложных картинок, чтобы было красиво, нужна интерполяция, не так просто. Я на опыте уже убедился, если под Винду, то апишный StretchBlt хорошо это делает. Дельфийские процедуры масштабирования работают хуже по качеству. А если самому, и хочешь качество, в сети есть алгоритмы (Scaling поищи).

PS Кстати, в рамках обмена опыта не объяснишь, что тут происходит? (не дружу я с математикой)
Zoom := Round(Exp(FRMMain.RG2.ItemIndex * Ln(2)));

PSS Как я и предполагал, замена на PaintBox решила проблему (код ниже). Либо замени, либо поколдуй над имиджом. Просто менять размеры мало, я не помню чего уж там ему не хватает, но что-то еще нужно сделать. Можешь просто присвоить свой битмап ему на битмап: Image.Bitmap := Bitmap; И автосайз задай ему, чтобы не менять размеры каждый раз явно. Так должно работать как надо.
Код:
procedure TFrmMain.FormCreate(Sender: TObject);
Var
 X,Y : Integer;
begin
 FRMMain.Left := 100;
 FRMMain.Top := 0;
 Bit := TBitMap.Create;
 Bit.Width := 50;
 Bit.Height := 50;
 BitZ := TBitMap.Create;
 BitZ.Assign(Bit);
 If ParamStr(1) = '' Then
  Begin
   Bit.Canvas.Brush.Color := 0;
   Bit.Canvas.FillRect(Bit.Canvas.ClipRect);
   Bit.Canvas.Pixels[0,0] := $0000FF;
   BitZ.Canvas.Draw(0,0, Bit);
  End
 Else
  Begin
   {...}
  End;
 FRMMain.IMGMain.Width := 50;
 FRMMain.IMGMain.Height := 50;
 FRMMain.IMGMain.Canvas.Draw(0,0,BitZ);
end;


procedure TFrmMain.ImgMainPaint(Sender: TObject);
begin
  (Sender as TPaintBox).Canvas.Draw(0, 0, BitZ);
end;

procedure TFrmMain.RG2Click(Sender: TObject);
Begin
 Zoom := Round(Exp(FRMMain.RG2.ItemIndex * Ln(2)));
 DrawBit;
End;


Procedure TFrmMain.DrawBit;
Var
 X,Y : Integer;
Begin
 BitZ.Width  := Bit.Width  * Zoom;
 BitZ.Height := Bit.Height * Zoom;
 For Y := 0 To BitZ.Height - 1 Do
  For X := 0 To BitZ.Width - 1 Do
   Begin
    BitZ.Canvas.Pixels[X,Y] := Bit.Canvas.Pixels[X Div Zoom, Y Div Zoom];
   End;
 FRMMain.IMGMain.Width  := BitZ.Width;
 FRMMain.IMGMain.Height := BitZ.Height;
 FRMMain.IMGMain.Canvas.Draw(0,0, BitZ);
 // FRMMain.IMGMain.Refresh; // это лишнее
End;
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 22.07.2010 в 11:05.
mutabor вне форума Ответить с цитированием
Старый 22.07.2010, 10:51   #4
SERG1980
Участник клуба
 
Аватар для SERG1980
 
Регистрация: 28.03.2007
Сообщений: 1,814
По умолчанию

Да и StrechDraw неплохо работает у того же имиджа
Вложения
Тип файла: zip 1.ZIP (380.3 Кб, 45 просмотров)
SERG1980 вне форума Ответить с цитированием
Старый 22.07.2010, 10:54   #5
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Цитата:
Да и StrechDraw неплохо работает у того же имиджа
Апишный стретч для фотографий качественнее, проверено.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Старый 22.07.2010, 11:58   #6
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Я все таки нашел решение для имаджа - просто, как все гениальное:
Код:
 FRMMain.IMGMain.Picture.Bitmap.Width := Bit.Width * Zoom;
 FRMMain.IMGMain.Picture.Bitmap.Height := Bit.Height * Zoom;
Похоже просто изменение размеров имаги не давало изменение размеров битмапа, ассоциированного внутри имаги. Интерполяция в данном случае даром не нужна, т.к. это смесь пеинта и моего формата файлов.
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ
Alex Cones вне форума Ответить с цитированием
Старый 22.07.2010, 12:29   #7
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Правильнее было бы так (автосайз должен быть задан имиджу):
FRMMain.IMGMain.Picture.Bitmap := BitZ;
И больше ничего не надо делать, изображение появится само.

А если BitZ уже был назначен имиджу, даже и этого делать не надо, тогда либо просто обновить его, либо он даже сам может среагировать на изменения в битмапе, нужно пробовать.

Кстати если ты будешь манипулировать битмапом имиджа, имей ввиду, ты манипулируешь на самом деле тем битмапом к-рый ранее назначил (присвоил свойству Bitmap) ему. Т.е. например, такой код:
Image.Canvas.Draw(0, 0, SomeBitmap);
может означать копирование самого в себя. Если до этого ссылка на SomeBitmap была присвоена в Picture.Bitmap.

Вношу поправку, это все не так. Image содержит независимый объект TBitmap, проверил адреса специально, и при присваивании скорее всего происходит неявное (код инкапсулирован где-то внутри имиджа) копирование битов одного битмапа в другой.
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог

Последний раз редактировалось mutabor; 22.07.2010 в 13:30.
mutabor вне форума Ответить с цитированием
Старый 22.07.2010, 12:53   #8
mutabor
Телепат с дипломом
Старожил
 
Аватар для mutabor
 
Регистрация: 10.06.2007
Сообщений: 4,929
По умолчанию

Вот самый простой вариант с TImage

Код:
procedure TFrmMain.FormCreate(Sender: TObject);
Var
 X,Y : Integer;
begin
 IMGMain.AutoSize := True; // одна строка
 FRMMain.Left := 100;
 FRMMain.Top := 0;
 Bit := TBitMap.Create;
 Bit.Width := 50;
 Bit.Height := 50;
 BitZ := TBitMap.Create;
 BitZ.Assign(Bit);
 If ParamStr(1) = '' Then
  Begin
   Bit.Canvas.Brush.Color := 0;
   Bit.Canvas.FillRect(Bit.Canvas.ClipRect);
   Bit.Canvas.Pixels[0,0] := $0000FF;
   BitZ.Canvas.Draw(0,0, Bit);
  End
 Else
  Begin
   {...}
  End;
 IMGMain.Picture.Bitmap := BitZ; // вторая строка, всё, больше ничего не надо
end;

procedure TFrmMain.RG2Click(Sender: TObject);
Begin
 Zoom := Round(Exp(FRMMain.RG2.ItemIndex * Ln(2)));
 DrawBit;
End;


Procedure TFrmMain.DrawBit;
Var
 X,Y : Integer;
Begin
 BitZ.Width  := Bit.Width  * Zoom;
 BitZ.Height := Bit.Height * Zoom;
 For Y := 0 To BitZ.Height - 1 Do
  For X := 0 To BitZ.Width - 1 Do
   Begin
    BitZ.Canvas.Pixels[X,Y] := Bit.Canvas.Pixels[X Div Zoom, Y Div Zoom];
   End;
 IMGMain.Picture.Bitmap := BitZ; // присваиваем еще раз когда нужно обновить
End;
The future is not a tablet with a 9" screen no more than the future was a 9" black & white screen in a box. It’s the paradigm that survives. (Kroc Camen)
Проверь себя! Онлайн тестирование | Мой блог
mutabor вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Графический редактор - zoom(лупа), Delphi vitalatron Помощь студентам 11 18.07.2012 10:12
Canvas ZET78 C++ Builder 5 21.05.2010 20:26
Delphi. Печать. Не работает Printer.Canvas.TextOut Alexander Karpenko Общие вопросы Delphi 4 02.03.2010 23:39
TP7 чтение из файла, работает но не работает!? Qousio Помощь студентам 7 02.06.2009 09:37
Библиотека НЕ работает с 2008, но работает с 2000 SQL namenike Общие вопросы C/C++ 0 26.05.2009 11:04