2015-11-28 46 views
0

我需要讀取存儲在XML文件中的JPG圖像並將其插入到SQLite數據庫的blob字段中。SQLite - 如何從XML文件插入JPG圖像(使用Delphi 2009)

我可以按照下面的代碼所示完成其中的一部分,但需要幫助。請靜靜地告訴我如何閱讀XML文件中的文本位圖,並將其插入到數據庫的blob字段中?

這就是我已經可以做的。

我可以使用一個Delphi XML數據使用以下的(簡化的)代碼在數據庫綁定單元和存儲文本的東西從它讀出的XML文件:

procedure TForm1.BtnReadXML(Sender: TObject); 
var 
    sql : string; 
    Data : XML_Binding_Photos.IXMLSuperStarReportType; 
    RecNum : integer; 

begin 
Data := XML_Binding_Photos.LoadSuperStarReport ('Photos.xml'); 
Database1.Open; 
try 
    RecNum := 2; 
    SQL := 'INSERT INTO main.Photos (id , firstname) VALUES (Data.record_[RecNum].ID, Data.record_[RecNum].Fname) ;' ; 
    Query1.Close; 
    Query1.selectSQL := sql; //insert the data 
    Query1.Open ; 
finally 
    Database1.Close; 
end; 
end; 

我還可以插入從光盤一JPG圖像到數據庫中使用流是這樣的:

procedure TForm1.Insert_JPG_PhotoFromFile(Sender: TObject); 
var 
    strm : TmemoryStream ; 
begin 
Database1.Open; 
strm := TmemoryStream.Create; 
try 
    strm.LoadFromFile('C:\...\testpic2.jpg'); 
    Query1.Close; 
    Query1.selectSQL := ('INSERT INTO main.Photos (id, photo) VALUES (''999'', :photo)'); 
    Query1.Params.ParamByName('photo').LoadFromStream(Strm,ftGraphic); 
    Query1.Open ; 
finally 
    strm.Free ; 
    DISQLite3Database1.close; 
end; 
end; 

但我的XML文件中有一個JPG圖像,編碼如下:

<Record> 
    <ID>14046</ID> 
    <Fname>Fred</Fname> 
    <Photo>/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAE - lots more of the same - txNxvd8dc44Htz/Ktx3Oe3T/AB96KK6DA//Z </Photo> 
    </Record> 

我可以使用XML數據綁定單元將構成位圖的字符讀入字符串或StringStream,但似乎無法將其正確保存爲數據庫中的斑點。我不想將每個XML圖像先保存爲jpg格式,部分原因是它已經以不同形式存在於光盤上,部分原因是xml文件中有成千上萬的圖像。另外,對於其他格式的圖像原因,我想把圖像放在數據庫中,而不是把它放在光盤上,只是存儲文件名)

+0

你知道如何從一個流一個文件以及如何將數據流存儲到數據庫中。所以你真正的問題可以簡化爲:如何從xml獲取圖像數據到流中。也許這個真正的問題引導你回答; o) –

+0

經過更多的調查,數據可能是base64編碼,可能jpg不是bmp。我使用了Indy組件TIdDecoderMIME,即PhotoData:= IdDecoderMIME1.DecodeString(PhotoData);然後在十六進制中查看結果,它以FFD8開頭,我知道這意味着它是jpg。所以我嘗試使用TheStream.Write(PhotoData [1],Length(PhotoData))創建一個流;後面跟着Query1.Params.ParamByName('the_photo')。LoadFromStream(TheStream,ftGraphic);但我仍然沒有在數據庫中得到正確的圖像(有一個圖像,但它只是彩色框和奇怪的符號 – user3209752

+0

Base64字符串是一個編碼流,只需找一個base64字符串流解碼器; o) –

回答

0

這適用於從XLM文件中獲取圖像並將其插入到blob字段中的sqlite數據庫中。

此代碼使用XML數據綁定單元,以便從xml文件中以base64PhotoData中存儲的字符串的形式讀取base64編碼圖像。 然後它使用我放在窗體上的Indy TIdDecoderMIME組件(IdDecoderMIME1:TIdDecoderMIME)將base64解碼爲Tbytes類型的變量(稱爲DecodeBytes) 然後,要將該字節數組存儲在blob字段中,每個字節需要被轉換回十六進制,並且整個事物都以'x'爲前綴來表示它是以十六進制表示的。
該解決方案不需要流(雖然也許它可以轉換這樣做,如果這種做法是更好)

(所有報價均爲單引號)

Procedure TForm1.btnimportphotosfromxmlClick(Sender: TObject); 
var 
    sql : string; 
    XMLData : XML_Binding_Photos.IXMLStarReportType; //in unit XML_Binding_Photos 
    i : integer; 
    Base64PhotoData, DecodedPhotoData : ansistring; 
    DecodeBytes: TBytes; 
    PhotoBlobs : string; 
begin 
XMLData := XML_Binding_Photos.LoadStarReport ('Photos.xml');  //open xml as a IXMLStarReportType , created from the xml file with the XML data binding wizard 
Base64PhotoData := SIMSData.record_[2].Photo;       //get the xml photo data from xml file, in this test case the second record 
DecodeBytes := IdDecoderMIME1.DecodeBytes(Base64PhotoData) ; //decode base64 charater string to an array of bytes 

PhotoBlobs := '';           //initialsise the string we are going to insert into the blob field 
for i := 0 to high(DecodeBytes) do    //convert each byte to a hex charater so that it can be inserted into a blob 
      PhotoBlobs := PhotoBlobs + inttohex(DecodeBytes[i],2); 

SQL := '' 
+'INSERT ' 
+'INTO StudentPhotos (id, photo ) ' 
+'  VALUES (''777'', ' 
+'    x''' + PhotoBlobs +''') ' ;       // note the prepending of lower case x to the hex byte string 


DISQLite3Database1.DatabaseName := 'C:\...\testphoto.db'; 
DISQLite3Database1.open 
try 
    DISQLite3Database1.Execute(sql); 
finally 
    DISQLite3Database1.close; 
end; 
+0

有一個名爲'TBytesStream'的類,你將從'TBytes'得到一個流,參見http://docwiki.embarcadero.com/Libraries/en/System.Classes.TBytesStream.Create –

+0

謝謝,我會研究一下儘管我不確定使用蒸汽有什麼區別會對這個答案產生什麼影響。 – user3209752