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;
Как насчет вопроса о преобразовании в png или jpeg? Как это делается? –
Я могу видеть это из ответа Криса, но он остался невысказанным в твоем. –
@Jordan: Я рассмотрел это с помощью параграфа «ForceDirectories» (сразу после второго примера «TPath.Combine»). –