Лидеры
Популярный контент
Показан контент с высокой репутацией 25.02.2017 в Сообщения
-
Как конвертировать растровую картинку в векторный TPath Firemonkey. How to convert a bitmap image (png, jpeg, bmp) into a Firemonkey vector TPath. Manual. Плюсы векторных изображений: Можно изменять размер избражения в любую сторону, уменьшать и увеличивать, без потери качества. Картинка всегда будет с четкими краями, без размытия по краям и квадратиков. Можно легко изменять в RunTime цвет заливки и обводной рамки, изменяя цвета в полях Fill и Stroke компонента TPath. Заливка как правило одна - это цвет из свойства Fill Color. Но ... цвет может быть и градиентом из множества цветов, который можно указать в диспетчере объектов, там же можно загрузить и Bitmap как текстуру в качестве заливки. Можно анимировать изображение, изменяя вышеуказанные свойства, а также направление градиента, размер, толщину обводной линии итд. Тоже можно менять и для Stroke свойства - обводной рамки. Минусы: Получаемое изображение упрощенное. Т.к. оно может содержать только один путь (Path) и одну плоскость. Возможно получиться скомбинировать множества TPath, положив их друг на друга с прозрачностью. Векторное изображение вычисляется и рисуется "в живую", поэтому потребуется больше ресурсов, чем при отрисовке обычных растровых картинок png, jpg, bitmap. Что означает нагрузку на аппаратную часть, замедление работы программы и более быструю разрядку мобильного устройства. Поэтому если и использовать подобные векторные изображения, то в случае если нужно отобразить большие картинки-символы на разных экранах (не иконки) - например на маленьком экране телефона, и на большом планшете и на еще большем Desktop экране. Хотя в примере \Samples\Object Pascal\Multi-Device Samples\User Interface\CustomListBox\CustomListBox.dproj используется векторная иконка\чекбокс очень простая. Преимущества векторного изображения наглядно: Ингредиенты: 1. Векторный редактор, я взял бесплатный inkscape, который можно скачать здесь . 2. Картинка. Желательно чтобы картинка была с большим разрешением, от 300px и больше. Если взять изображение маленького размера, например 48x48 или 64x64, то контуры получатся не такими точными. И хотя inkscape все равно применит сглаживание контуров, и квадратиков вы не увидите, обводные линии могут получиться другой формы, к примеру более жирными или могут слиться с другими линиями. Исходное изображение лучше брать в формате PNG, т.к. JPEG оставляет артефакты в виде точек, в итоге программа при трассировке может захватить и их, что не желательно. Конечно же если другого исходника нету, то смысла конвертировать jpg в png нет - качество не улучшится. Основной метод конвертации - это трассировка изображения, - когда алгоритм ищет края и обводные линии, и на основе их рисует свои. Потому качественные результаты получаться если брать изображение с одной плоскостью, без теней, градиентов и деталей, в стиле Windows 8\10 или Android. Т.н. Flat (плоский) icon. 3. IDE RAD Studio Delphi или С++ Приступим. Запускаем incscape. Размер исходной png картинки 668x720. 1. Меню File > Open - указываем путь. Иконка загрузилась. 2. Нажимаем левой кнопкой мыши на картинку, чтобы она выделилась. 3. Меню Path > Trace Bitmap. Сразу выберите чекбокс Live Preview (см скриншот). Здесь есть разные методы, но нам нужна секция Single Scan: Creates a Path. Методы нужно подбирать визуально, "на глаз". Можно также использовать и секцию Multiply Scans, а затем скомбинировать пути в один (Path > Combine), т.к. нам нужен один путь, и один набор. Путь (Path) это набор инструкций о том как и сколько рисовать линий-векторов. Для нашего конкретного случая, этой конкретной иконки, оптимальный вариант Color Quantization и количество цветов = 2. 4. Нажимаем OK и закрываем окно. Появилось наше изображение залитое черным цветом - это и есть наша векторная картинка. Стоит заметить что прямо под ним лежит наше исходного изображение. Чтобы его удалить нужно отодвинуть мышкой векторное изображение, выделить исходную картинку и удалить ее клавишей Delete. 5. Вы можете отредактировать пути, выбрав в левой панели инструмент Edit Paths By nodes (F2) или добавить фильтры\эффекты в меню Path > Path Effects. В данном примере я ничего не менял. 6. File Save As > inkscape SVG . 7. Открываем полученный SVG файл в блокноте или в Lister тотал коммандера. Ищем массив чисел, который обычно начинается со строчки "<path". Находим эту строчку, нам нужно набор символов, который идет после буквы "d=", к примеру d="m 397.33334,c -48.1 ...-0.326 -1.64129,-0.66405 z" и копируем все, что внутри кавычек в буфер. 8. Далее в RAD IDE кидаем на форму TPath. В Object Inspector WrapMode устанавливаем в Fit, и в поле Data вставляем из буфера наш код. 9. Меняем Fill и Stroke цвета на нужные нам значения (здесь я установил желтый цвет и увеличил толщину обводки (Stroke)). Еще пару примеров. Дерево - параметры Brightness Cutoff, Threshold 0.370 . Как видите здесь оптимальнее подходит метод Brightness Cutoff. Здесь исходная png картинка - это дерево черного цвета, я ее распознал, и затем добавил в TPath, а в свойстве Fill указал градиент от черного до зеленого. Наушники - Edge Detection 0. Конечно конкретно в этом случае нужно подчищать изображение. Иногда бывает что при вставке пути в TPath, компонент его отображает некорректно, если снова зайти в DATA TPath, то окажется что часть данных потеряна. Что исправить эту ситуацию, нужно путь упростить. Это значит что после шага 4, нужно выбрать в incscrape меню Path > Simplify, затем снова сохранить файл. Правда Simplify в incscrape работает не очень хорошо, часто загругляет прямые участки. Лучше делать Simplify в Adobe Illustrator. Статья опубликована на сайте fire-monkey.ru и возможно будет изменяться и дополняться. Автор: ENRGY 24. 02. 175 баллов
-
Нужно ли разрешение Write External Storage
Равиль Зарипов (ZuBy) и ещё один отреагировал Евгений Корепов за вопрос
По моему опыту это разрешение не нужно. Включая вариант с установкой приложения на SD-карту. Разрешение требуется при использовании папок TPath.GetShared% или когда явно указано использование External Memory в http://docwiki.embarcadero.com/RADStudio/Seattle/en/Standard_RTL_Path_Functions_across_the_Supported_Target_Platforms P.S. Некоторые мои приложения опубликованные в маркете использует единственное разрешение Internet, при этом успешно пишут конфиги в GetHomePath. Проблем с установкой на SD-карту тоже не замечено. Сейчас гугль заставляет публиковать политику конфиденциальности при использовании разрешений, так что чем меньше разрешений, тем лучше. Да и пользователи с большим доверием относятся к приложению с минимальными разрешениями. Жаль что пуши требуют разрешение Идентификационные данные - пользователи постоянно обвиняют приложение в попытках украсть что то с их телефонов ;-)2 балла -
Я определяю так: var FFirstDistance, FLastDistance: integer; .. procedure TformMainMenu2.FormGesture(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean); begin case EventInfo.GestureID of igiZoom : begin if (not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags)) and (not(TInteractiveGestureFlag.gfEnd in EventInfo.Flags)) then FLastDistance := EventInfo.Distance; if (TInteractiveGestureFlag.gfBegin in EventInfo.Flags) then FFirstDistance := EventInfo.Distance; if (TInteractiveGestureFlag.gfEnd in EventInfo.Flags) then begin // zoom out if ( FFirstDistance > FLastDistance ) then begin Plan.Scale := 0.5; end; // zoom in if ( FFirstDistance < FLastDistance ) then begin Plan.Scale := 1.0; end; end; end; end; end;2 балла
-
В общем, я бы исправил так: добавил локальную переменную Abort: Boolean; в TWinHTTPClient.DoExecuteRequest, до цикла передачи данных вызвал бы коллбек с объёмом файла, так же как происходит при загрузке файла на ПК - первый коллбек вызывается с нулевым объёмом переданных данных. LRequest.DoReceiveDataProgress(0, DataLength, 0, Abort); В цикл добавил бы проверку на прекращение загрузки while (LRequest.FSourceStream.Position < LRequest.FSourceStream.Size) and (not Abort) do В конце цикла вызывал бы коллбек с объёмом файла и количеством переданных байт. Первый параметр коллбека - StatusCode получить на данном этапе скорее всего нельзя, или я не понял как, поэтому передаю ноль. LRequest.DoReceiveDataProgress(0, DataLength, LRequest.FSourceStream.Position, Abort); Полный текст исправленной функции.1 балл
-
NetHTTPClient передача файла и OnReceiveData
Евгений Корепов отреагировал Maximus за вопрос
Да вот смотрю на то что они понаписали и думаю, то ли они вообще не предусмотрели вызов этого коллбека при отдаче файла, то ли забыли... Вот эта функция вызывается вне зависимости от того куда мы загружаем файл: к себе или на сервер. Разница начинается на этой сроке LExecResult := DoExecuteRequest(LRequest, LResponse, AContentStream); При загрузке на ПК эта функция не входит в блок кода, помеченный // Send data. TWinHTTPClient.DoExecuteRequest выполняется полностью и продолжается выполнение процедуры THTTPClient.ExecuteHTTPInternal, в которой выполнение доходит до строки if not SameText(LRequest.FMethodString, sHTTPMethodHead) then LResponse.DoReadData(LResponse.FStream); откуда вызывается функция где и начинается загрузка файла на ПК. Отсюда уже и происходит вызов нашего коллбека в цикле, пока файл не загрузится. FRequestLink.DoReceiveDataProgress(LStatusCode, LExpected, LReaded, Abort); С передачей на сервер всё обстоит не так. После того как мы попали в функции TWinHTTPClient.DoExecuteRequest в блок кода, помеченный // Send data, мы там и остаёмся в цикле, пока файл не будет загружен, там разумеется нет никакого вызова коллбека, и только после того как файл будет загружен и мы выйдем из TWinHTTPClient.DoExecuteRequest, то так же попадаем в TWinHTTPResponse.DoReadData и там вызывается FRequestLink.DoReceiveDataProgress(LStatusCode, LExpected, LReaded, Abort); который перед циклом и который вызывается в итоге после окончания загрузки файла на сервер. Дальше мы входим в цикл, но он досрочно завершается вместе с процедурой на строке if LSize = 0 then Break; Самое забавное, что в цикле при передаче на сервер, даже флага Abort нет, значит прервать никак передачу нельзя, ну разве что объект уничтожать прямо во время работы.1 балл -
1 балл
-
NetHTTPClient передача файла и OnReceiveData
krapotkin отреагировал Евгений Корепов за вопрос
Скорее всего глюки, посмотрите исходники, возможно найдете ошибку. Компонент NetHTTPClient "новый" и по традиции наполнен багами. Вот к примеру OnValidateServerCertificate разработчики сломали в XE8, а починили только в Берлине. Куки тоже были сломаны сознательно (скопипастили кусок кода не в то место, тремя строками ниже чем нужно), и чинились два апдейта, если не ошибаюсь. Еще одна традиция - исправление только одного бага в одном компоненте за один апдейт, так что проще будет исправить код самому.1 балл -
При LongTap срабатывают и OnTap и OnClick
Alisson R Oliveira отреагировал Barbanel за вопрос
У изображения нужно настроить на какие жесты он реагирует. Кинь на форму TGestureManager, потом настрой поля как показано ниже в коде. OnClick - срабатывает при касании объекта, срабатывает и в виндовс и на мобильных устройствах. OnTap - срабатывает несколько интеллектуальнее, причем только на мобильных устройствах (в виндовс не срабатывает). Упрощенно, он срабатывает только если ты коротко тапнул на контрол, если ты нажал на контрол и повел пальцем, скроля контент или скроля родительский ScrollBox, OnTap НЕ сработает. // инициализация Image.Touch.GestureManager := gestManager; Image.Touch.InteractiveGestures := [TInteractiveGesture.LongTap]; Image.OnGesture := FormGesture; .. // обработка жеста procedure TfrmMain.FormGesture(Sender: TObject; const EventInfo: TGestureEventInfo; var Handled: Boolean); begin case EventInfo.GestureID of igiLongTap : begin DoSomething(); end; end; end;1 балл -
Большое спасибо что поддерживаете статьи в актуальном состоянии! Я также часто ссылаюсь на ваши статьи на других сайтах - англоязычных. Что удивительно подобная информация редко вcтречается на англоязычных сайтах, к примеру про Alarm Manager и Delphi нет ни одной статьи, даже на сайте Embarcadero этот вопрос долгое время висел без ответа, пока я не дал ссылку на вашу статью. Непопулярность Delphi Mobile как раз и связана с тем, кроме цены, что на многие вопросы почти нет ответов, при этом Java сообщество пестрит готовыми Copy Paste решениями, что увеличивает и без того большую армию пользователей. Но Java нет на iOS. И на Java не сделаешь кроссплатформенный проект с единым кодом и GUI, поэтому Delphi здесь на шаг впереди. Поэтому мне и показалось важным указать на ньюанс с JAR в темах связанными с DEX (заодно кстати и осветили баг с батником, помните javac -source 1.7 -target 1.7? - ведь на этом этапе у человека изучающего Delphi может пропасть желание изучать дальше), столько плясок с бубном с этим dex, и разбросать чтобы больше людей увидели более удобный и простой вариант.1 балл
Эта таблица лидеров рассчитана в Москва/GMT+03:00