-
Постов
396 -
Зарегистрирован
-
Посещение
-
Победитель дней
16
Активность репутации
-
Martifan отреагировална Евгений Корепов в Helper для TBitmap - асинхронная загрузка картинки из URL
Пока тестировал хелпер в боевом проекте он потихоньку оброс исрпавлениями/улучшениями:
Загрузка из потока сделана через TBitmapSurface - это позволяет избежать множества глюков. LoadFromStream вынесен из Synchronize (основного потока) в поток HTTPClient - по результатам бенчмарка операция оказалась самая жручая. После исправления интерфейс перестал залипать совсем. Добавлен overload вариант с передачей в процедуру TListItemImage - для использования в TListView и корректной перерисовки подгруженных картинок через AListItemImage.Invalidate. unit BitmapAsyncLoader; interface uses FMX.Graphics, FMX.Surfaces, System.Net.HttpClient, System.Types, System.Classes, FMX.ListView.Types, FMX.ListView.Appearances; type TBitmapAsyncLoader = class helper for TBitmap procedure LoadFromURLAsync(const AUrl : String); overload; procedure LoadFromURLAsync(const AUrl : String; const AListItemImage : TListItemImage); overload; end; implementation var AHTTPClient : THTTPClient; procedure TBitmapAsyncLoader.LoadFromURLAsync(const AURL : String); begin try AHTTPClient.BeginGet( procedure (const ASyncResult: IAsyncResult) var AHTTPResponse : IHTTPResponse; ABitmapSurface : TBitmapSurface; begin if Not ASyncResult.IsCompleted then exit; try AHTTPResponse:=THTTPClient.EndAsyncHTTP(ASyncResult); except end; if Assigned(AHTTPResponse) and (AHTTPResponse.StatusCode = 200) then begin ABitmapSurface:=TBitmapSurface.Create; if TBitmapCodecManager.LoadFromStream(AHTTPResponse.ContentStream, ABitmapSurface, CanvasClass.GetAttribute(TCanvasAttribute.MaxBitmapSize)) then TThread.Synchronize(Nil, procedure begin if Assigned(Self)then Assign(ABitmapSurface); ABitmapSurface.Free; end ) else ABitmapSurface.Free; end; end, AURL ); except end; end; procedure TBitmapAsyncLoader.LoadFromURLAsync(const AURL : String; const AListItemImage : TListItemImage); begin try AHTTPClient.BeginGet( procedure (const ASyncResult: IAsyncResult) var AHTTPResponse : IHTTPResponse; ABitmapSurface : TBitmapSurface; begin if Not ASyncResult.IsCompleted then exit; try AHTTPResponse:=THTTPClient.EndAsyncHTTP(ASyncResult); except end; if Assigned(AHTTPResponse) and (AHTTPResponse.StatusCode = 200) then begin ABitmapSurface:=TBitmapSurface.Create; if TBitmapCodecManager.LoadFromStream(AHTTPResponse.ContentStream, ABitmapSurface, CanvasClass.GetAttribute(TCanvasAttribute.MaxBitmapSize)) then TThread.Synchronize(Nil, procedure begin if Assigned(Self) and Assigned(AListItemImage) then begin AListItemImage.BeginUpdate; Assign(ABitmapSurface); AListItemImage.Invalidate; AListItemImage.EndUpdate; end; ABitmapSurface.Free; end ) else ABitmapSurface.Free; end; end, AURL ); except end; end; initialization AHTTPClient:=THTTPClient.Create; finalization if Assigned(AHTTPClient) then AHTTPClient.DisposeOf; end. Тестовый проект, на этот раз с ListView (по кнопке добавляется 100 итемов) прилагаю.
BitmapAsyncLoaderListView.7z
-
Martifan получил реакцию от Barbanel в как очистить память клавиатуры
Спасибо большое добрый человек действительно работает
-
Martifan отреагировална Евгений Корепов в как очистить память клавиатуры
Нашел еще более изящный способ, без исчезновения/показа клавиатуры:
procedure TForm1.Button1Click(Sender: TObject); begin Memo1.SelectAll; Memo1.DeleteSelection; end;
-
Martifan получил реакцию от MrAnderson в Получить голос из микрофона потоками
Доброго времени сутки
недавно для себя открыл что можно из микрофона получить данные потоками:
Uses ..., Androidapi.JNI.Media; procedure TForm1.Button1Click(Sender: TObject); var bufferSize: integer; buffer: TJavaArray<Byte>; M: TMemoryStream; begin audioRecord := TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC, 44100, TJAudioFormat.JavaClass.CHANNEL_IN_MONO, TJAudioFormat.JavaClass.ENCODING_PCM_16BIT, 44100 * 2); (audioRecord as JAudioRecord).startRecording; buffer := TJavaArray<Byte>.Create(8820); (audioRecord as JAudioRecord).read(buffer, 0, 8820); (audioRecord as JAudioRecord).stop; audioRecord.release; buffer заполняется данными я проверил все работает (можно код прописать чтобы этот buffer проигрывал)
audioRecord := TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC, 44100, TJAudioFormat.JavaClass.CHANNEL_IN_MONO, TJAudioFormat.JavaClass.ENCODING_PCM_16BIT, 44100 * 2); <--- как мне кажется здесь видно что это формат Wave
я пытаюсь передать это все серверу:
IdUDPClient1.SendBuffer(IdUDPClient1.Host, IdUDPClient1.Port, RawToBytes(buffer, buffer.Length)); сервер запущен на Windows но не получается я слышу только пикание
Вопрос:
как мне передать этот поток серверу (среды Windows) и как его проигрывать на сервере, может у кого есть опыт работы с этом сфере или какой нибудь документация имеется или какой нибудь предложение есть как все это сделать все совете и предложении очень важен
Заранее спасибо согласитесь интересно использовать микрофон так и не дожидая пока он создаст файл
всем удачи
-
Martifan получил реакцию от Dev в [Android] Как свернуть приложение?
Нашел еще один способ:
Uses Androidapi.Helpers; procedure TfMain.SpeedButton11Click(Sender: TObject); begin SharedActivity.moveTaskToBack(True); end; -
Martifan отреагировална #WAMACO в Загрузить изображение из библиотеки
https://github.com/rzaripov1990/ModernListView
-
Martifan отреагировална Brovin Yaroslav в Описание TfgSignature - Получение подписи на устройстве
Описание:
Назначение: Получение подписи клиента в графическом виде. Позволяет получить векторную подпись клиента на устройстве и сохранить ее в файл с любым разрешением Поддерживаемые платформы: Windows, OSX, Android, iOS Демо проект: Samples\SignatureDemo\SignatureDemo.dproj Доступен с версии: R102 Возможности:
Экспорт подписи в файл или поток с любым разрешением (TfgSignature.SaveToFile, TfgSignature.SaveToStream). При этом в файле подпись кадрируется, то есть пустые не заполненные области справа, слева, сверху и снизу игнорируются. Доступно изменение точности записи подписи (TfgSignature.TrackingAccurancy). Возможность получить в процентах степень заполнения подписи клиента (TfgSignature.CalculatePercentFilling, TfgSignature.IsValidSignature) Возможность установить цвет (TfgSignature.Stroke) Возможность задать цвет заднего фона (TfgSignature.Brush) Доступно редактирование длительности отображения уведомления (TfgToast.Duration) Возможность менять глобальные параметры отображения всех тостов в рамках приложения (TfgToast.DefaultBackgroundColor, TfgToast.DefaultMessageColor и TfgToast.DefaultPadding) Скриншоты:
-
Martifan отреагировална Ry Koo в Фотография из альбома
я делал так:
создайм стандартный экшн TakePhotoFromLibrary
у экшна событие DidFinishTaking:
procedure TForm1.TakePhotoFromLibraryAction1DidFinishTaking(Image: TBitmap); // Здесь забираю выбранную фотку к себе в каталог и отображаю её в приложении
begin
image.SaveToFile(TPath.GetDocumentsPath+PathDelim+'OurImage.png');
Image1.Bitmap:=image;
end;
Здесь юзера спрашиваю разрешения порыться в его картинках:
PermissionsService.RequestPermissions([JStringToString(TJManifest_permission.JavaClass.READ_EXTERNAL_STORAGE)],
procedure(const APermissions: TArray<string>; const AGrantResults: TArray<TPermissionStatus>)
begin
if (Length(AGrantResults) = 1) and (AGrantResults[0] = TPermissionStatus.Granted) then
// Юзер разрешил читать файлы. Выполняем экшн.
TakePhotoFromLibraryAction1.Execute;
end);
Вот. У меня работает.
-
Martifan получил реакцию от Виталий Иванов в Audio Streaming
сам у Bass есть этот модуль разберусь и результат вылажу
-
Martifan отреагировална Alex7wrt в Audio Streaming
Под Android я тоже делал аудио чат родными средствами, но через Bass получилось лучше и проще. В частности, там буферизация из коробки, можно эффекты накладывать, например усиление голоса при записи через микрофон. Поэтому и предложил, ведь под Bass код, что под Android, что под iOS, один и тот же.
Поделиться не сложно. Ниже надергал основную схему из того приложения, о котором говорил выше.
uses FMX.Radio.Bass; var BLoaded: boolean; chanPlay, ChanMic: Dword; avail, freq: word; buffer: TIDBytes; procedure TForm1.OnCreate(Sender: TObject); begin //Создаем UDP сервер UDP_Rec:=TIDUDPServer.Create; with UDP_Rec do begin DefaultPort:=UDP_RecPort; BufferSize:=1600; BroadcastEnabled:=true; Active:=true; end; freq:=16000; //Частота дискретизации setlength(buffer,UDP_Rec.BufferSize); BLoaded:=BASS_Init(-1, 44100, 0, nil, nil); //Подключаем библиотеку BASS_RecordInit(-1); //Инициализируем запись end; //Захват звука с микрофона procedure TForm1.Recording(Sender: TObject; const Point: TPointF); begin isrecording:=not isrecording; if isrecording then begin UDP_Rec.OnUDPRead:=nil; chanMic:=BASS_RecordStart(freq, 1, 0, nil, nil); VoiceThread:=TVoiceThread.Create; //Создание потока для отправки по UDP end end; //Передача буффера в потоке procedure TVoiceThread.Execute; begin while isrecording do begin try avail:=BASS_ChannelGetData(chanMic, nil, BASS_DATA_AVAILABLE); if avail>=UDP_Rec.BufferSize then begin //Если в буффере собралось не меньше 1600 байт, отправляем try BASS_ChannelGetData(chanMic, buffer, UDP_Rec.BufferSize); UDP_Rec.Broadcast(Buffer,UDP_RecPort); except end; end; finally sleep(20); end; end; BASS_ChannelStop(chanmic); BASS_StreamFree(chanmic); end; //Создание канала для воспроизведения звука из буффера: procedure TForm1.receiving(Sender: TObject); begin chanPlay:= BASS_StreamCreate(freq, 1, 0, STREAMPROC_PUSH, nil); UDP_Rec.OnUDPRead:=UDP_RecRead; BASS_ChannelPlay(chanPlay, false); end; //Получаем буффер из UDP procedure TForm1.UDP_RecRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle); begin try BASS_StreamPutData(chanPlay, AData,length(AData)) except end; end; Bass.zip
-
Martifan получил реакцию от FREEFAR в iOS Speech To Text
https://github.com/jimmckeeth/FireMonkey-Android-Voice/
-
Martifan получил реакцию от Brovin Yaroslav в iOS Speech To Text
https://github.com/jimmckeeth/FireMonkey-Android-Voice/
-
Martifan отреагировална Brovin Yaroslav в [Статья] Жизненный цикл объектов в Delphi. Часть 1. Windows, OSX. Что же использовать Destroy, Free, FreeAndNil или DisposeOf?
Ссылка: http://yaroslavbrovin.ru/object_life_cycle_in_delphi_part_1_windows_osx-ru/ Автор: Ярослав Бровин С появлением мобильных платформ в мире Delphi, произошли серьезные изменения в жизненном цикле объектов. Послужившие причиной многих проблем и вопросов, а как правильно кроссплатформенно удалять объекты. В этой статье детально рассматриваем жизненный цикл объектов на разных платформах и даём ответы на важные вопросы, которые могут побеспокоить даже опытных Delphi разработчиков.
-
Martifan отреагировална Равиль Зарипов (ZuBy) в [Статья] Онлайн-сервисы в помощь разработчику по дизайну
Ссылка: http://blog.rzaripov.kz/2017/01/blog-post.html
Автор: Зарипов Равиль @ZuBy
Описание: Онлайн-сервисы в помощь разработчику по дизайну
-
Martifan отреагировална Равиль Зарипов (ZuBy) в как позвонить на iPhone?
Вот патч от @Brovin Yaroslav
iOSapi.CoreTelephony.pas.patch.zip
-
Martifan отреагировална Равиль Зарипов (ZuBy) в Custom Font
для берлина
для сиетла
для того чтобы на IOS работать с кастомными шрифтами, это нужно прописать в info.plist.TemplateiOS.xml (для берлина)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <%VersionInfoPListKeys%> <%ExtraInfoPListKeys%> <key>UIAppFonts</key> <array> <string>FontAwesome.ttf</string> </array> <key>ITSAppUsesNonExemptEncryption</key><false/> </dict> </plist>
-
Martifan получил реакцию от azm_ezm_ivan в Получить голос из микрофона потоками
я может не увидел но где код как у вас написана если так старайтесь чтобы он играл то не получится ну не правильно но крайне случай используйте ваш таймер но это неправильно лучше через TTask
-
Martifan отреагировална Равиль Зарипов (ZuBy) в Python в рамках приложения для Android и iOS
что за обработка планируется? код настолько сложный что его невозможно повторить на delphi?
-
Martifan отреагировална Равиль Зарипов (ZuBy) в Python в рамках приложения для Android и iOS
думаю что нет. какой смысл в этом?
-
Martifan получил реакцию от Rusland в Получить голос из микрофона потоками
Доброго времени сутки
недавно для себя открыл что можно из микрофона получить данные потоками:
Uses ..., Androidapi.JNI.Media; procedure TForm1.Button1Click(Sender: TObject); var bufferSize: integer; buffer: TJavaArray<Byte>; M: TMemoryStream; begin audioRecord := TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC, 44100, TJAudioFormat.JavaClass.CHANNEL_IN_MONO, TJAudioFormat.JavaClass.ENCODING_PCM_16BIT, 44100 * 2); (audioRecord as JAudioRecord).startRecording; buffer := TJavaArray<Byte>.Create(8820); (audioRecord as JAudioRecord).read(buffer, 0, 8820); (audioRecord as JAudioRecord).stop; audioRecord.release; buffer заполняется данными я проверил все работает (можно код прописать чтобы этот buffer проигрывал)
audioRecord := TJAudioRecord.JavaClass.init(TJMediaRecorder_AudioSource.JavaClass.MIC, 44100, TJAudioFormat.JavaClass.CHANNEL_IN_MONO, TJAudioFormat.JavaClass.ENCODING_PCM_16BIT, 44100 * 2); <--- как мне кажется здесь видно что это формат Wave
я пытаюсь передать это все серверу:
IdUDPClient1.SendBuffer(IdUDPClient1.Host, IdUDPClient1.Port, RawToBytes(buffer, buffer.Length)); сервер запущен на Windows но не получается я слышу только пикание
Вопрос:
как мне передать этот поток серверу (среды Windows) и как его проигрывать на сервере, может у кого есть опыт работы с этом сфере или какой нибудь документация имеется или какой нибудь предложение есть как все это сделать все совете и предложении очень важен
Заранее спасибо согласитесь интересно использовать микрофон так и не дожидая пока он создаст файл
всем удачи
-
Martifan отреагировална Brovin Yaroslav в [RX] [FGX] Описание версии 0.7.1.118
Ссылка на скачивание (Только для RAD Studio Berlin?fgx_0.7.1.118.zip Инструкция по установке: "Инструкция по установке набора компонентов FGX" Описание
Эта версия включает в себя следующий набор компонентов:
Дизайнер итемов - дизайнер итемов. TfgToast (UPDATED) - класс отображения быстрых сообщений TfgFlipView - слайдер изображений. Поддерживает несколько способов переключения фотографий при помощи эффектов и сдвигов. При первом использовании ОБЯЗАТЕЛЬНО прочитать инструкцию "TfgFlipView - Инструкция загрузки стиля" TfgPositionAnimation - анимация свойств типа TPosition TfgPosition3DAnimation - анимация свойств типа TPosition3D TfgBitmapLinkAnimation - анимация свойств типа TBitmapLink TfgProgressDialog (UPDATED) - Компонент для отображения диалогового окна в момент выполнения длительной фоновой операции, когда время выполнения фоновой операции можно оценить. TfgActivityDialog (UPDATED) - компонент для отображения диалогового окна в момент выполнения длительной фоновой операции, когда время выполнения операции не возможно адекватно оценить. TfgActionSheet (UPDATED) - Аналог контекстного меню для мобильных платформ. TfgColorsPanel - Палитра цветов с возможностью выбора цвета. TfgGradientEdit (UPDATED) - Компонент выбора градиента. TfgLinkedLabel - Метка поддерживающая открытие Web ссылки в браузере по умолчанию. TfgApplicationEvents - компонент с возможностью легко задать обработчики на основные события приложения: Отслеживание смены состояния приложения, простой, обновление и выполнение действий Actions, Изменение ориентации устройства и тд. TfgVirtualKeyboard - компонент облегчающий работу с виртуальной клавиатурой. Позволяет задать пользовательские кнопки над виртуальной клавиатурой под iOS, а так же отлавливать события по отображению и скрытию клавиатуры. (UPDATED) Зарегистрированы все стилевые объекты на вкладке "FGX: Style objects" Список изменений
TfgActionSheet: Добавлен новый вариант темы Theme = Custom и свойство ThemeID, позволяющий для андроида указать идентификатор своей темы диалога. Теперь доступна возможность создать свой вариант диалога для андроида. Изменен порядо срабатывания событий OnCancel, OnHide в реализации на iOS. Раньше срабатывали OnHide -> OnCancel, Теперь: OnCancel -> OnHide Обновлен пример Общие улучшения в читабельности кода TfgProgressDialog, TfgActivityDialog: Добавлен новый вариант темы Theme = Custom и свойство ThemeID, позволяющий для андроида указать идентификатор своей темы диалога. Обновлен пример Общие улучшения в читабельности кода TfgGradientEdit: Добавлено событие OnPointRemoved, срабатывающее, когда точка удалена из градиента. Обновлен пример TfgToast: Исправлена ошибка на iOS, приводящая к AV при многочисленном отображении тостов. (Спасибо Сергею Пьянкову за найденную ошибку) Регистрация стилевых объектов: Теперь регистрируются только те объекты, которые не добавлены в палитру. -
Martifan получил реакцию от Kitty в Проблема с анимацией
Спасибо за ответы решенные нашлось, может кому пригодится
TAnimator.AnimateIntWait(Rectangle1, 'Position.Y', -300); TAnimator.AnimateInt(Rectangle1, 'Position.Y', 144,1,TAnimationType.Out,TInterpolationType.Back); -
Martifan отреагировална Равиль Зарипов (ZuBy) в Проблема с анимацией
ну вы же понимаете как работает анимация?
1) реорганизация положения контрола на родителе
2) реорганизация положения компонентов внутри контрола
3) сработает ресайз контрола и всех его дочерних компонентов, что вызовет содержащий в обработчиках код
если высота контрола для которого применяется анимация равна 100 пикселям, все это повторится 100 раз
-
Martifan отреагировална AngryOwl в Проблема с анимацией
Как один из вариантов решения подобных проблем - как можно меньше создавать/размещать на "двигающихся" элементах различных компонент.
Чем меньше компонент - тем меньше "перерисовок". Отсюда - какие именно компоненты, тоже играет роль. Если это TLabel или TPanel, или другие несложные компоненты, то это "простые" элементы. Соответственно их перерисовка не сложна. Если это элементы посложнее, типа TListBox, в котором у всех его TListBoxItem определены свойства Text, Detail и, возможно, другие, типа вставлены еще и картинки и т.д., то это будет уже "весомый" элемент.
Что еще важно - какой стиль вы применили к тому или иному компоненту. Если у вас простой TPanel имеет сложный стиль, переопределенный вами, то и его "прорисовка", соответственно, будет дольше происходить.
Не забывайте о том, что можно сделать предварительную загрузку стиля. Это сильно уменьшит время первого отображения вашего элемента.
Ну есть еще вариант... Он будет, относительно, "мудреней"... Все зависит от вашего желания)
Пример, насколько я помню, можно посмотреть тут. Суть заключается в том, что можно сделать скрин вашего элемента (панели) и работать с ним (показывая его в момент анимации и отключая поле выполненной анимации). Подобных примеров достаточно, в том числе на сайте Embarcadero.
-
Martifan получил реакцию от Евгений Корепов в Linux Just Turned 25 and Delphi is Coming to Celebrate
http://blog.marcocantu.com/blog/2016-august-linux-25-delphi-coming.html