• 0
Anasazi

Поочередная загрузка изображений в TImage

Вопрос

Всем доброго времени суток. Возникла необходимость решить такую задачу: в таблице базы MySQL хранится список изображений и их URL. Необходимо получить этот список массивом. Затем загрузить изображения и поочередно с интервалом показать их в TImage.

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

Раньше для получения изображений использовал такую процедуру. Но вопрос, где хранить изображения перед демонстрацией их в TImage? Создавать несколько MemoryStream?

procedure LoadWebImage(url: string; image: TBitmap);
var
  idhttp : TNetHTTPClient;
  ms : TMemoryStream;
begin
 IdHTTP := TNetHTTPClient.Create(nil);
  ms := TMemoryStream.Create;
  try

    idhttp.Get(url, ms);
    ms.Position := 0;
    image.LoadFromStream(ms);

  finally
    ms.Free;
    idhttp.Free;
  end;
end;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

15 ответов на этот вопрос

  • 0

вместо TNetHttpClient вам нужен THttpClient

хотите - храните в TStream, хотите - в TBitmap

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
1 минуту назад, krapotkin сказал:

вместо TNetHttpClient вам нужен THttpClient

хотите - храните в TStream, хотите - в TBitmap

А как думаете, как лучше получить URL'ы? PHP пусть возвращает одной строкой и потом разбивать по разделителю?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

не понял вопроса. но в принципе вообще все равно. 
исходим из того, что запросы - медленные. а программа быстрая.

как выгоднее так и делаем

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Привет. Я не использовал такой путь. Организуйте свой проект.

procedure setLogo(ListView: TListView; code, url: string; id: Integer);
  var
   Cache: string;
   T: TThread;
 begin
   Cache := TPath.GetCachePath + '/AzerBoxPlus/Cache/';
   if not TFile.Exists(Cache + code + '.png') then
   begin
     T := TThread.CreateAnonymousThread(
     procedure
     var
       HTTP: TIdHTTP;
       MS: TMemoryStream;
     begin
       MS := TMemoryStream.Create;
       HTTP := TIdHTTP.Create(nil);
       try
         try
           HTTP.Get(url, MS);
           TThread.Synchronize(TThread.CurrentThread,
             procedure()
             begin
               ListView.Items[id].Bitmap.LoadFromStream(MS);
               MS.SaveToFile(Cache + code + '.png');
             end);
         except
           MS.Free;
         end;
       finally
         HTTP.Free;
		MS.Free;
		end;
     end);
     T.start;
   end else
   begin
     T := TThread.CreateAnonymousThread(
     procedure
     begin
       TThread.Synchronize(TThread.CurrentThread,
       procedure()
       begin
         ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png');
       end);
     end);
     T.start;
   end;
 end;

setLogo(ListView, 'name', 'url', index);

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
18 часов назад, AliZairov сказал:

T := TThread.CreateAnonymousThread( procedure begin TThread.Synchronize(TThread.CurrentThread, procedure() begin ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png'); end); end); T.start;

с учетом Thread и Synchronize  тут по сути написано

ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png');

 

ENERGY понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
14 часа назад, krapotkin сказал:

с учетом Thread и Synchronize  тут по сути написано

ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png');

Я не до конца понимаю. Вы задали мне вопрос?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

нет. просто констатирую, что вместо этих 10 строк можно было оставить исходную одну

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
1 час назад, AliZairov сказал:

Я не до конца понимаю. Вы задали мне вопрос?

@AliZairov

Эта конструкция:

end else
   begin
     T := TThread.CreateAnonymousThread(
     procedure
     begin
       TThread.Synchronize(TThread.CurrentThread,
       procedure()
       begin
         ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png');
       end);
     end);
     T.start;
   end;
 end;

равнозначна одной строчке (ее можно заменить:):

ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png');

 

TThread.Synchronize - означает "остановить текущий поток, и запустить указанную процедуру в главном (GUI) потоке".

 

 

Еще один момент 

 

 

 except
    MS.Free;  << эта строка не нужна, т.к. код в finally будет выполнен при срабатывании исключения.
  end;
finally
  HTTP.Free;
  MS.Free;
end;

Если вам нужно загасить исключение - то можно сделать пустой блок, без кода. 

try 

except 

end;

Изменено пользователем ENERGY

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
В 19.05.2017 в 16:10, Anasazi сказал:

А как думаете, как лучше получить URL'ы? PHP пусть возвращает одной строкой и потом разбивать по разделителю?

Собрать массив на пхп и сделать json_encode, на стороне Делфи распарсить json и дальше грузить ссылки

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
11 час назад, ENERGY сказал:

равнозначна одной строчке (ее можно заменить:):

ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png');

Это верно только в том случае, если мы заранее знаем, что процедура SetLogo будет всегда вызываться только из основного потока. Если что-то менять - я бы код

    T := TThread.CreateAnonymousThread(
     procedure
     begin
       TThread.Synchronize(TThread.CurrentThread,
       procedure()
       begin
         ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png');
       end);
     end);
     T.start;

заменил бы следующим:

TThread.ForceQueue(TThread.CurrentThread,
  procedure()
  begin
    ListView.Items[id].Bitmap.LoadFromFile(Cache + code + '.png');
  end);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
2 часа назад, dnekrasov сказал:

Это верно только в том случае, если мы заранее знаем, что процедура SetLogo будет всегда вызываться только из основного потока. 

Если так рассуждать, тогда нужно каждое обращение к элементу интерфейса облачать в ForceQueue конструкцию. "А вдруг с другого потока обратятся"?

Имхо "не следует множить сущности без необходимости".

Изменено пользователем ENERGY

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
В 19.05.2017 в 14:05, AliZairov сказал:

Привет. Я не использовал такой путь. Организуйте свой проект.


procedure setLogo(ListView: TListView; code, url: string; id: Integer);

...

 @ENERGY, я говорил об этой процедуре, а ее можно вызвать откуда угодно. Ведь задача и состоит в том, чтобы в теле этой процедуры синхронизировать обращение к элементам GUI с главным потоком. Ведь кто нам мешает к ней обратиться следующим образом:

T := TThread.CreateAnonymousThread(
  procedure
  begin
    setLogo(ListView, 'name', 'url', index);
  end);
T.start;

Кстати, в этом случае, внутри нее можно вообще избавиться от CreateAnonymousThread

Изменено пользователем dnekrasov

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

@dnekrasov

Кстати у меня есть привычка, - методы, которые вызываются в отдельном потоке, к их именам обычно добавлю слово Thread. SetLogoThread. Очень рекомендую от путанницы.

Ну и если спорить дальше, то SetLogo не будет вызван в отдельном потоке, т.к. название метода уже намекает на GUI, а значит только главный поток, и анонимный поток внутри. :) 

 

 

Изменено пользователем ENERGY

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

@ENERGY

Хорошая привычка :). У меня тоже она есть, вот только слово - Operation :D.

Насчет вызова в отдельном потоке - была у меня недавно задачка: на всех открытых в данный момент окнах обновлять некую инфу с заданным интервалом. Так я её реализовал вызовом одной процедуры изнутри постоянно крутящегося потока. Но эту инфу надо было отобразить еще и при открытии формы - вот тогда мне очччень помог метод ForceQueue 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Добрый вечер. Я использовал этот код для веб-телепроекта ABP. Были некоторые ошибки в коде он знает. Но, видя, полные необходимые процедуры. Мне нужно было, чтобы сделать эту систему из такой библиотеки. Picasso

5921c4936da2e_ScreenShot2017-05-21at20_47_09.png.d6c8093dced3feb177099152e5e98f55.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Похожие публикации

    • Автор: ENERGY
      Как залить с Delphi Android в базу MySql строки, я примерно понял - составляем GET запрос и вставляем строки в параметры, затем считываем их в PHP скрипте и в базу.
      А вот как быть с картинкой. Как добавить картинку через PHP скрипт из программы на Android?
      POST запрос? Кто нибудь делал такое уже?
      Спасибо 
       
      P.s. На данный момент FireDAC не поддерживает работу с MySQL из под Android. Пока только SQLite и  InterBase ToGo. Даже если в будущем будет поддерживать, многие на этом форуме рекомендуют не использовать прямое подключение к базам из под мобильных систем, а использовать прямые GET запросы к примеру к PHP скриптам. Это связано с нестабильностью интернета т.к. так интернет может часто переключаться (от вышки к вышке) и менять параметры подключения. 
    • Автор: denprox
      Доброго времени суток! Подскажите, как узнать оригинальный размер картинки, загруженной в TImage ?
    • Автор: Илья Захаров
      Пишу приложение под iOS и Android... Создал базу данных на хостинге написал скрипты на PHP для получения данных. Пробовал GET запросом получить данные, возвращает пустые значения. Если через браузер смотреть то массивы данных возвращает правильно. Кто ни буть цепочки может написать как правильно это все реализовать.... Какие компоненты и какие статьи почитать... Заранее спасибо...
    • Автор: Илья Захаров
      Помогите пожалуйста, поделитесь информацией или примерчиком. Есть база данных MySQL на хостинге Макхост. Мне нужно для соединения,работы с ней использовать SSH протокол я не понимаю как это сделать... может в компонентах FireDAC есть какая ни будь фича?  
    • Автор: Anasazi
      Всем добрый день! Получаю координаты с помощью yandex api. Использую вот такой код:
          try
          ////Запрос на Яндекс для получения координат
           MainForm.NetHTTPClient1.Get
          ('https://geocode-maps.yandex.ru/1.x/?geocode='+
          'Кунгур'+
          ',+'
          +street+
          '+улица,+дом+'+
          house, Result);
          finally
          end;
       
      Код отрабатывает нормально, но если ну устройстве нет интернета, то приложение просто вылетает. Подскажите пожалуйста как поправить.
      Приложение для iOS.
    • Автор: netlink
      Коллеги, добрый день!
      Есть некий набор байт, который представляет собой пришедший через HTTP поток байт, который внутри JPEG.
      vImagesBytes: TBytes; Получаю, запихиваю это в MemoryStream
      vBMPMemoryStream := TMemoryStream.Create; try vMemoryStream.WriteData(vImagesBytes, Length(vImagesBytes)); vMemoryStream.Seek(0, TSeekOrigin.soBeginning);  
      Вопрос:
      как из стрима получить сначала JPEG, в потом конвертнуть его в BMP, чтобы загрузить в TBITMAP?
      Или есть более простой путь?
    • Автор: Rusland
      Как реализовать показ ProgressBar при загрузке фотографии на сервер? Интересует как именно определять сколько байт передано?
      Используется компонент NetHTTPClient.
    • Автор: Rusland
      Вроде видел где-то пример передачи через NetHTTPClient файла (*.png или *.jpg) на сервер, но не могу вспомнить где.
      Помогите с кодом отправки файла.
       
      PS. Инди компоненты не интересуют, не хочется их инспользовать
    • Автор: Satellite
      Возможно ли вывести 9-patch в Timage? Если нет, то куда можно импортировать изображение такого формата? 
    • Автор: AlexG
      Возник следующий вопрос:
      Допустим есть "сложная" форма, внешний вид которой должен быть нестандартным и на которой расположено N-ное количество компонент (исходим из того, что их много, некоторые из них - динамические, например - вывод видео с камеры).
      "Нестандартный вид" подразумевает: наличие тени у формы, измененный внешний вид, отличный от вида по умолчанию в любой ОС.
      Непосредственно вопрос звучит так.
      Какая из двух следующих реализаций будет работать быстрее (отрисовка/обновление этой формы при обновлении компонент: текста, списков, вывод видео и т.д.):
      Оба вида форм предопределяются в стиле.
      ВАРИАНТ 1.
      - Тень формы реализована в виде компонента TImage с подгруженным PNG изображением.
      - Контур формы реализован компонентом TRectangle с "окантовкой" и заливкой прямоугольника заданным цветом (все без градиентов)
      - Шапка формы реализована вторым прямоугольником TRectangle без "окантовки", но с заливкой другим цветом (без градиента)
      ВАРИАНТ 2. Вся форма задана одним объектом TStyleObject в котором в качестве свойств установлены:
      - SourceLookup - ссылка на PNG-изображение в данном стиле
      - SourceLink - создан TBitmapLink, у которого заданы свойства CapInsets и SourceRect
      Внешний вид у них будет практически одинаковый (хотя во втором случае он будет более корректным на любой ОС и при использовании любой видео-карты, чего не скажешь о первом варианте).
      Однако, интересует именно СКОРОСТЬ отрисовки в обеих случаях!
      Интересует именно теория, с точки зрения реализации самой FMX.
      З.Ы. Предполагаю, что вопрос больше к разработчикам FMX, но возможно у кого-то уже есть опыт работы с подобными задачами...
  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу