2014-02-12 1 views
0

Мне нужно, хотелось бы сохранить изображения на пользовательское устройство (iOS или Android) после загрузки изображения из межсетевых экранов, чтобы пользователь не загружался изображение много раз.Как сохранить растровые изображения на IOS с помощью Delphi XE5

Насколько я понимаю, на iOS я могу сохранять только форматы файлов JPG или PNG. Как преобразовать файл растрового изображения из delphi в файл .JPG или .PNG? Я вижу в VCL TPNGImages поддерживаются, но не для FMX.

Когда я использую SomeBitmap.bitmap.SaveToFile(GetHomePath+PathDelim+'Documents'+PathDelim+'Pictures'+PathDelim+PictureName+'.png'; , он ничего не делает и не исключает исключение. Помощь? ?

Разработка приложений для IOS/Android с помощью Delphi xe5

ответ

1

TBitmap.SaveToFile прекрасно работает (по крайней мере, на Android - Я не могу говорить с прошивкой), когда дано действительное имя и местоположение файла. Однако, если вы этого не сделаете, он просто бесшумно выходит из строя без ошибок, по-видимому, из-за того, что исключения на некоторых мобильных операционных системах сложны. Таким образом, фактическая проблема связана с предоставлением имени файла или местоположения, и в этом случае, похоже, это место.

Никогда не предполагайте, что вы можете угадать местоположение папок на разных платформах. Всегда используйте одну из папок, возвращаемых функциями в TPath. Они перечислены в документации Delphi под номером Standard RTL Path Functions across the Supported Target Platforms; в этом случае вы ищете TPath.GetPicturesPath, который на Android возвращает что-то вроде '/storage/emulated/0/Pictures'. (Согласно документации, в настоящее время на устройствах iOS нет каталога доступных изображений, хотя на симуляторе, похоже, есть ограничение. Это может быть ограничение самой iOS: вам нужно будет проверить документацию Apple iOS, чтобы определить, что , однако. Соответствующее место на iOS находится в том месте, которое было возвращено TPath.GetDocumentsPath, которое, согласно документации XE5, является чем-то вроде '/var/mobile/Applications/<application ID>/Documents'.)

Во-вторых, никогда не конкатенировать части пути вручную. Используйте TPath.Combine (от блока IOUtils), который автоматически добавит разделитель пути в нужное место, если это необходимо. Если вам нужно сделать это так, вы можете объединять несколько звонков, чтобы получить требуемый уровень подпапок:

Для читаемости/ремонтопригодность (IOS место продемонстрировали):

Dest := TPath.Combine(TPath.GetDocumentsPath, 'mydir'); 
Dest := TPath.Combine(Dest, 'tests'); 

или (для краткости):

Dest := TPath.Combine(TPath.Combine(TPath.GetDocumentsPath, 'mydir'), 'tests'); 

Если вам нужно создать папки по пути, TDirectory.CreateDirectory будет создавать их, как будет SysUtils.ForceDirectories; оба доступны на всех поддерживаемых платформах. (Обратите внимание, что это версия SysUtils из ForceDirectories, что является кросс-платформенным, а не версия FileCtrl, которая является Windows, специфичны.)

if not TDirectory.Exists(Dest, False) then 
    TDirectory.CreateDirectory(Dest); 

// or 
// SysUtils.ForceDirectories(Dest); 

Что касается форматов, FMX.Graphics.TBitmap (через TBitmapCodecManager класс) обеспечивает поддержку следующих форматов во всех поддерживаемых платформах:

JPEG (.jpeg, .jpg) 
TIFF (.tiff, .tif) 
GIF 
PNG 
BMP 

Вот пример преобразования из растрового изображения в .png на Windows; У меня нет устройства Android, чтобы проверить его там, но аналогичный код должен работать для вас (при условии, что вы указываете правильные расположения папок и имена файлов, как упоминалось выше). Скомпилирован и протестирован на 64-битной версии Win7 с использованием XE5 Update 2.

procedure TForm1.FormShow(Sender: TObject); 
var 
    BmpIn, BmpOut: TBitmap; 
    SaveParams: TBitmapCodecSaveParams; 
begin 
    BmpIn := TBitmap.Create; 
    try 
    BmpIn.LoadFromFile('E:\TempFiles\ScreenCaps\CheckBoxChecked.bmp'); 

    BmpOut := TBitmap.Create; 
    try 
     BmpOut.Assign(BmpIn); 
     SaveParams.Quality := 100; 
     BmpOut.SaveToFile('E:\TempFiles\ScreenCaps\CheckBoxChecked.png', @SaveParams); 
    finally 
     BmpOut.Free; 
    end; 
    finally 
    BmpIn.Free; 
    end; 
end; 
+0

Как насчет вопроса о преобразовании в png или jpeg? Как это делается? –

+1

Я могу видеть это из ответа Криса, но он остался невысказанным в твоем. –

+1

@Jordan: Я рассмотрел это с помощью параграфа «ForceDirectories» (сразу после второго примера «TPath.Combine»). –

2

Существуют различные вещи, чтобы уточнить здесь:

  1. Попросту говоря, источник FMX имеет чрезвычайно глупое исключение-фобии, несмотря на то отдельные случаи могут получить фиксированной в течение долгого времени. Одним из таких примеров этой фобии в XE5 является TBitmap.SaveToFile, который, как правило, терпит неудачу при подаче недопустимого ввода.

  2. Как говорит Кен Уайт, вы не должны предполагать, где находится папка, определенная системой. Тем не менее, я не очень увлечен IOUtils, хотя он должен использоваться (если вы не вызываете собственные функции API напрямую). В двух словах, используя простой подход PathDelim, было бы совершенно справедливо, но для IOUtils глупо не соблюдало традиционные соглашения об именах Delphi RTL, в которых XxxPath означало «включает разделитель обратного пути»; из-за этого расхождения вступает в игру TPath.Combine.

  3. Ваше предположение о том, что FMX TBitmap, как и класс VCL, сохраняет формат BMP, неверно - по умолчанию сохраняет значение PNG.

+1

@ Ken White упоминает 'SysUtils.ForceDirectories' в своем сообщении. Это создаст каталог, если он не существует. – Sentient

+0

Не могли бы вы взглянуть на аналогичную проблему здесь https://forums.embarcadero.com/thread.jspa?messageID=639090򜁲 –

 Смежные вопросы

  • Нет связанных вопросов^_^