На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

Не приветствуется поднятие старых тем. Если ваш вопрос перекликается со старой темой, то для вопроса лучше создать новую тему, а старую указать в первом сообщении с описанием взаимосвязи.

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
  
> Скачать изображение
    Нужно скачать изображение по УРЛ и передать скаченную матрицу в TImage.
    Пытался скачать изображение вот так:
    ExpandedWrap disabled
      procedure TDownloader.Load;
      var
        I:TidHTTP;
        S:TMemoryStream;
        JPEG: TJPEGImage;
      begin
        i:=TIdHTTP.Create(nil);
        S:=TMemoryStream.Create;
        JPEG:=TJPEGImage.Create;
      try
        I.Get(URL,S);
        S.Position:=0;
        Jpeg.LoadFromStream(S);
        Image.Picture.Assign(JPeg);
      finally
        i.Free;
        S.Free;
        JPeg.Free;
      end;
      end;

    Но даже в потоке ,такой код тормозит перерисовку всей формы.Как быть?
      1) Что-бы загрузка не тормозила перерисовку, перерисовка должна быть отделена от загрузки.
      Подсказка хранить картинку надо в TBitmap;
      2) Что-бы загрузка не тор мазила не надо каждый раз устанавливать TCP и HTTP соединения. Держи их открытыми. Тот же принцип отдели загрузку от создания соединения.

      Добавлено
      PS. Есть предположение что и загрузка сделана с ошибкой странно что работает.
        Нужно во главе потока грузить.. Execute; а не в отдельных его процедурках типа .Load;....
        тогда ни чего не будет тормозить..
          faust777,
          Естественно,
          ExpandedWrap disabled
              TDownloader = class(TThread)
            Protector
            чтобы развеять сомнения faust777, покажи, откуда вызывается метод Load
              Цитата Pavia @
              PS. Есть предположение что и загрузка сделана с ошибкой странно что работает.

              ExpandedWrap disabled
                procedure TDownloader.Load;
                var
                  I:TidHTTP;
                  S:TMemoryStream;
                  JPEG: TJPEGImage;
                begin
                i:=TIdHTTP.Create(nil);
                S:=TMemoryStream.Create;
                JPEG:=TJPEGImage.Create;
                try
                try
                 I.Get(URL,S);
                except
                end;
                  S.Write(Pointer(S)^, SizeOf(S));
                  S.Position:=0;
                  Jpeg.LoadFromStream(S);
                try
                if Assigned(Image)and(@Image<>nil)and(not Self.Terminated) then
                begin
                Image.Picture.Assign(Jpeg);
                end;
                except
                end;
                finally
                  i.Free;
                  S.Free;
                  JPeg.Free;
                end;
                end;


              Добавлено
              MBo, Каким образом корректно обработать ситуацию ,когда поток еще грузит картинку ,а юзер завершает приложение?
              У меня такая последовательность действий вызывает AV и Еврика показывает утечку памяти (i:=TIdHTTP.Create(nil); - здесь ).
              Сообщение отредактировано: Protector -
                Всё не смотрел, но на будущее не помешает подумать, чему равно SizeOf(S)? (TMemoryStream)

                И что должна делать волшебная строка?
                S.Write(Pointer(S)^, SizeOf(S));

                для чего @Image<>nil ?
                Сообщение отредактировано: MBo -
                  Апдейт:
                  ExpandedWrap disabled
                    procedure TDownloader.Execute;
                    var
                      I:TidHTTP;
                      S:TMemoryStream;
                      JPEG: TJPEGImage;
                    begin
                      inherited;
                    i:=TIdHTTP.Create(nil);
                    S:=TMemoryStream.Create;
                    JPEG:=TJPEGImage.Create;
                    try
                    try
                     I.Get(URL,S);
                    except
                    end;
                      S.Position:=0;
                      Jpeg.LoadFromStream(S);
                    try
                    Image.Picture.Assign(Jpeg);
                    except
                    end;
                    finally
                      i.Free;
                      S.Free;
                      JPeg.Free;
                    end;
                    end;


                  А в чем причина утечки памяти?
                    ExpandedWrap disabled
                      Image.Picture.Assign(Jpeg);
                    :o это как у тебя "поток" определяет Где находиться Image?

                    А в общем, как то так)..
                    ExpandedWrap disabled
                      type
                        TForm1 = class(TForm)
                          Button1: TButton;
                          Image1: TImage;
                          procedure Button1Click(Sender: TObject);
                        private
                          { Private declarations }
                        public
                          { Public declarations }
                        end;
                       
                        TDownloader = class(TThread)
                        private
                          HTTP:TidHTTP;
                          JPEG: TJPEGImage;
                          procedure EndDown;
                        protected
                          procedure Execute; override;
                        public
                          constructor Create(CreateSuspended: Boolean);
                        end;
                       
                      var
                        Form1: TForm1;
                       
                      implementation
                       
                      {$R *.dfm}
                       
                      procedure TForm1.Button1Click(Sender: TObject);
                      begin
                       TDownloader.Create(False);
                      end;
                       
                      constructor TDownloader.Create(CreateSuspended: Boolean);
                      begin
                        inherited Create(CreateSuspended);
                      end;
                       
                      procedure TDownloader.Execute;
                      var
                        S:TMemoryStream;
                      begin
                       HTTP:= TIdHTTP.Create(nil);
                       S:= TMemoryStream.Create;
                       JPEG:=TJPEGImage.Create;
                       try
                        HTTP.Get('http://forum.sources.ru/uploads/av-150083.jpg',S);
                        S.Position:=0;
                        JPEG.LoadFromStream(S);
                         Synchronize(EndDown);
                       except
                        FreeAndNil(S);
                        FreeAndNil(HTTP);
                        JPeg.Free;
                       end;
                         if Assigned(S) then FreeAndNil(S);
                         if Assigned(JPEG) then JPEG.Free;
                         if Assigned(HTTP) then FreeAndNil(HTTP);
                      end;
                       
                      procedure TDownloader.EndDown;
                      begin
                       Form1.Image1.Picture.Assign(JPEG);
                      end;
                      Цитата faust777 @
                      ExpandedWrap disabled
                        Image.Picture.Assign(Jpeg);
                      :o это как у тебя "поток" определяет Где находиться Image?

                      А в общем, как то так)..
                      ExpandedWrap disabled
                        type
                          TForm1 = class(TForm)
                            Button1: TButton;
                            Image1: TImage;
                            procedure Button1Click(Sender: TObject);
                          private
                            { Private declarations }
                          public
                            { Public declarations }
                          end;
                         
                          TDownloader = class(TThread)
                          private
                            HTTP:TidHTTP;
                            JPEG: TJPEGImage;
                            procedure EndDown;
                          protected
                            procedure Execute; override;
                          public
                            constructor Create(CreateSuspended: Boolean);
                          end;
                         
                        var
                          Form1: TForm1;
                         
                        implementation
                         
                        {$R *.dfm}
                         
                        procedure TForm1.Button1Click(Sender: TObject);
                        begin
                         TDownloader.Create(False);
                        end;
                         
                        constructor TDownloader.Create(CreateSuspended: Boolean);
                        begin
                          inherited Create(CreateSuspended);
                        end;
                         
                        procedure TDownloader.Execute;
                        var
                          S:TMemoryStream;
                        begin
                         HTTP:= TIdHTTP.Create(nil);
                         S:= TMemoryStream.Create;
                         JPEG:=TJPEGImage.Create;
                         try
                          HTTP.Get('http://forum.sources.ru/uploads/av-150083.jpg',S);
                          S.Position:=0;
                          JPEG.LoadFromStream(S);
                           Synchronize(EndDown);
                         except
                          FreeAndNil(S);
                          FreeAndNil(HTTP);
                          JPeg.Free;
                         end;
                           if Assigned(S) then FreeAndNil(S);
                           if Assigned(JPEG) then JPEG.Free;
                           if Assigned(HTTP) then FreeAndNil(HTTP);
                        end;
                         
                        procedure TDownloader.EndDown;
                        begin
                         Form1.Image1.Picture.Assign(JPEG);
                        end;

                      Каждую с n картинок ,загружает отдельный поток .Зачем синхронизация?
                        для VCL например)

                        А уж чего там каждую или как..извени..не телепат.

                        Вот это ты что показал?
                        ExpandedWrap disabled
                            S.Position:=0;
                            Jpeg.LoadFromStream(S);
                          try
                          Image.Picture.Assign(Jpeg);
                          except
                          end;
                          finally
                            i.Free;


                        Такое в принципе не может работать. компилятор это даже запустить не даст..

                        Давай тогда больше когда своего, а не не понятные обрывки.
                          faust777,
                          ExpandedWrap disabled
                            constructor TDownloader.Create(const URL: string; var Img: TImage);
                            begin
                            inherited Create(false);
                            Self.Url:=URL;
                            Self.Image:=Img;
                            Self.FreeOnTerminate:=true;
                            end;

                          Это весь код .

                          Добавлено
                          Цитата faust777 @
                          компилятор это даже запустить не даст..

                          Не утрируйте .Все работает ,корректно пока не наступает описанная ситуация .
                            Цитата faust777 @
                            except
                            FreeAndNil(S);
                            FreeAndNil(HTTP);
                            JPeg.Free;
                            end;
                            if Assigned(S) then FreeAndNil(S);
                            if Assigned(JPEG) then JPEG.Free;
                            if Assigned(HTTP) then FreeAndNil(HTTP);
                            end;


                            Если написать вместо except слово finally, то можно обойтись одним экземпляром удалений ресурсов.
                            Единственный ньюанс - ожидается ли подавление исключений? Или это такой side-effect?
                              Цитата Mr.Delphist @
                              Если написать вместо except слово finally, то можно обо....

                              Тут уж кому как) да и тема не про то..вроде)..

                              Щас то в чём уже проблема.. ведь очевидно что зависаний ни каких нет..
                              А утечки..Без них Indy наверно ни когда не будет... Насколько критично это, вот в чём вопрос..
                              Или как вариант ещё, сделать своё "закрытие программы"... что бы когда "юзер завершает приложение", всё остановливалось..очищалось..
                                Цитата Protector @
                                Это весь код .

                                Цитата Protector @
                                А в чем причина утечки памяти?

                                Деструктор потока покажи. :D
                                  Цитата faust777 @
                                  А в общем, как то так)..

                                  А удалять поток кто будет?

                                  Добавлено
                                  Я бы сделал так (схематично, некомпилируемо):

                                  ExpandedWrap disabled
                                    const
                                      MSG_IMGGOT = WM_APP + 1;
                                     
                                    TDownThread.Create(URL: string; ResponseWnd: HWND);
                                    begin
                                      fURL := URL;
                                      fResp := ResponseWnd;
                                      inherited Create(False);
                                      FreeOnTerminate := True;
                                    end;
                                     
                                    TDownThread.Execute;
                                    begin
                                      ... Str := GetURL(fURL); ...
                                      Img := TJPEG.Create;
                                      Img.LoadFromStream(S);
                                      ... // free idHTTP, Stream...
                                      PostMessage(fResp, MSG_IMGGOT, 0, LPARAM(Img));
                                    end;
                                     
                                    TForm.Click
                                    begin
                                      TDownThread.Create('blabla.com/1.jpg', Handle);
                                    end;
                                     
                                    TForm.MsgImgGot(Msg: TMessage); // message MSG_IMGGOT;
                                    var
                                      Img: TJPEG;
                                    begin
                                      Img := TJPEG(Msg.lParam);
                                      Image1.Assign(Img);
                                      Img.Free;
                                    end;
                                  Сообщение отредактировано: Fr0sT -
                                    оно не свалится с ошибкой без синхронизации? я бы эвентом сделал передав через него указатель на картинку и вызвав его в методе с синхронизацией. ну а при создании потока обработчик в форме повесил бы
                                      medved_68,
                                      ExpandedWrap disabled
                                        destructor TDownloader.Destroy;
                                        begin
                                          inherited;
                                        end;

                                      :huh:

                                      Добавлено
                                      Fr0sT, Вот обращение к изображению по хендлу -это ,как по мне, выход .

                                      Добавлено
                                      Цитата antonn @
                                      оно не свалится с ошибкой без синхронизации?
                                      ,
                                      Нет :)
                                      Сообщение отредактировано: Protector -
                                        Fr0sT,
                                        Следуя вашей идеи :
                                        ExpandedWrap disabled
                                          procedure TDownloader.Execute;
                                          var
                                            I:TidHTTP;
                                          begin
                                          inherited;
                                            i:=TIdHTTP.Create(nil);
                                          try
                                          try
                                            I.Get(URL,S);
                                          except
                                          end;
                                            SetImg;
                                          finally                                                          
                                            FreeAndNil(i);
                                          end;
                                           
                                          end;
                                           
                                          procedure TDownloader.SetImg;
                                          var
                                            copydata:COPYDATASTRUCT;
                                          begin
                                              ZeroMemory(@copydata, SizeOf(TCopyDataStruct));
                                              copydata.dwData:=0;
                                              copydata.cbData:=S.Size;
                                              copydata.lpData:=S.Memory;
                                              SendMessage(Self.hCanv,WM_COPYDATA,Longint(Self.hCanv),lparam(@copydata));
                                          end;
                                           
                                          procedure TForm1.RecvData(var Msg: TWMCopyData);
                                          var
                                            S:TMemoryStream;
                                            J:TJPEGImage;
                                            Data: COPYDATASTRUCT;
                                          begin
                                            Data:=Msg.CopyDataStruct^;
                                            S:=TMemoryStream.Create;
                                            J:=TJPEGImage.Create;
                                          try
                                            S.Write(Data.lpData^,Data.cbData);
                                            S.Position:=0;
                                            J.LoadFromStream(S);
                                            Image1.Assign(J);
                                          finally
                                            S.Free;
                                            J.Free;
                                          end;
                                          end;


                                        А изображение передается поврежденным.
                                        Сообщение отредактировано: Protector -
                                          Цитата antonn @
                                          оно не свалится с ошибкой без синхронизации?

                                          C чего бы? Изображение создается в потоке и отправляется форме, после этого в потоке не используется. Таким образом у меня передаются объекты и строки и ничего не валится.
                                          Цитата Protector @
                                          Следуя вашей идеи :

                                          Нет уж, пардоньте, в моей идее не было ничего от приведенной каши.
                                          Начать хотя бы с того, что судя по названию поля hCanv оно содержит хэндл явно не главной формы. А оно должно посылаться именно главной форме.
                                          Затем, copydata - на фига? Если уж так не хочется делать true асинхронный способ - пожалуйста, SendMessage(MainFormHandle, MSG_IMGGOT, 0, LPARAM(Img)) будет синхронным (пока форма не обработает сообщение - поток ждет). Также можно передать и мемористрим, без необходимости копировать его. Метод в таком случае сокращается до
                                          ExpandedWrap disabled
                                            Thread.Execute;
                                            begin
                                              ...download to stream...
                                              SendMessage(MainFormHandle, MSG_IMGGOT, 0, LPARAM(Str));
                                              Str.Free;
                                            end;
                                             
                                            MainForm.MsgImgGot;
                                            begin
                                              Str := TMemoryStream(Msg.lParam);  
                                              J.LoadFromStream(S);
                                              Image1.Assign(J);
                                              J.Free;
                                            end;


                                          Добавлено
                                          Тем не менее, это не ТРУ, и я это посоветовал исключительно в образовательных целях.
                                            Fr0sT, результат идентичен .

                                            Добавлено
                                            Цитата Fr0sT @
                                            Тем не менее, это не ТРУ, и я это посоветовал исключительно в образовательных целях.

                                            А что же трю?
                                              Цитата
                                              C чего бы? Изображение создается в потоке и отправляется форме, после этого в потоке не используется. Таким образом у меня передаются объекты и строки и ничего не валится.

                                              я никогда так не делал и не разбирался, но думал что в сообщении придет указатель на объект созданный в потоке
                                                Цитата Protector @
                                                medved_68,
                                                CollapsedWrap disabledLine numbers off

                                                destructor TDownloader.Destroy;
                                                begin
                                                inherited;
                                                end;

                                                А. Тогда вопросов нет. ;) Особенно в разрезе:
                                                Цитата Protector @
                                                ExpandedWrap disabled
                                                  i:=TIdHTTP.Create(nil);
                                                :D
                                                  medved_68,Это локальная переменная .
                                                    Вопрос для Protector
                                                    Цитата Protector @
                                                    medved_68,Это локальная переменная .

                                                    А напомни, где выделяется память для объектов на стеке или в куче?
                                                    И когда он освобождается?
                                                    Сообщение отредактировано: Pavia -
                                                      Pavia,
                                                      ExpandedWrap disabled
                                                        procedure TDownloader.Load;
                                                        var
                                                          I:TidHTTP;
                                                          S:TMemoryStream;
                                                          JPEG: TJPEGImage;
                                                        begin
                                                          i:=TIdHTTP.Create(nil);
                                                          S:=TMemoryStream.Create;
                                                          JPEG:=TJPEGImage.Create;
                                                        try
                                                          I.Get(URL,S);
                                                          S.Position:=0;
                                                          Jpeg.LoadFromStream(S);
                                                          Image.Picture.Assign(JPeg);
                                                        finally
                                                          i.Free; //Вот где .
                                                          S.Free;
                                                          JPeg.Free;
                                                        end;
                                                        end;
                                                        Цитата Pavia @
                                                        И когда он освобождается?

                                                        Цитата Protector @
                                                        finally
                                                        i.Free; //Вот где .

                                                        Как там по жанру должно быть? А...Вопросов не имею...Так? :D
                                                          Мне кажется ,сама Еврика вызывает утечку. Чем еще можно проверять утечки памяти?

                                                          Добавлено
                                                          medved_68,По жанру , в этом месте идет оператор case.
                                                            Protector
                                                            http://www.gunsmoker.ru/2009/05/blog-post_24.html
                                                            Советую при поиске утечки потренироваться на примерах.
                                                              так все таки в #22 я неправ и через сообщение (не copydata) отправляется полная копия (новый экземпляр) или все таки ссылка (и автору кода пока просто светит удача (например, что объект не уничтожился при завершении потока до того как с ним закончилась работа вне потока))?
                                                                antonn, ну придет указатель на объект, созданный в потоке. И? Он же динамически создан, а не на стеке. Всё тут нормально.
                                                                Цитата Protector @
                                                                А что же трю?

                                                                См. первый мой пост
                                                                Цитата Protector @
                                                                результат идентичен

                                                                А проверь сначала без потока. Если не сработает - приведи полный код потока и обработчиков формы на данный момент
                                                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                                                0 пользователей:


                                                                Рейтинг@Mail.ru
                                                                [ Script execution time: 0.1202 ]   [ 15 queries used ]   [ Generated: 24.10.26, 03:05 GMT ]