2014-02-12 141 views
0

我需要將圖像保存到用戶設備(iOS或Android)後,我從interwebs下載圖像,以便用戶不必下載圖像無數次。如何使用Delphi XE5在IOS上保存位圖圖片

據我瞭解,在iOS上,我只能保存JPG或PNG文件格式。如何將位圖文件從delphi轉換成.JPG或.PNG圖片文件? 我在VCL中看到TPNGImages支持,但不支持FMX。

當我使用SomeBitmap.bitmap.SaveToFile(GetHomePath+PathDelim+'Documents'+PathDelim+'Pictures'+PathDelim+PictureName+'.png'; 它不會做任何事情或拋出異常。 幫助? ?

通過德爾福XE5

回答

1

TBitmap.SaveToFile適用於iOS/Android的發展非常好(至少在Android的 - 我不能到iOS說吧)給出一個有效的文件名和位置時。但是,如果你不這樣做,它只是在沒有錯誤的情況下靜靜地失敗,可能是因爲在一些移動操作系統上異常很難處理。所以實際的問題是提供的文件名或位置,在這種情況下,它似乎是它的位置。

永遠不要假設你可以猜測跨平臺的文件夾位置。請始終使用TPath中函數返回的文件夾之一。他們被列在德爾福文檔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 

下面是在Windows上從位圖到.png的轉換示例;我沒有一個Android設備在那裏測試它,但類似的代碼應該爲你工作(如上所述,只要你指定了有效的文件夾位置和文件名)。使用XE5 Update 2在Win7 64位上進行編譯和測試。

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. 正如Ken White所說的,你不應該假定系統定義的文件夾位於何處。也就是說,儘管需要使用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򜁲 –