簡體   English   中英

使用 SSIS 從 XML 中提取 base64 編碼圖像

[英]Extracting base64-encoded images from XML using SSIS

我有一個復雜的場景,客戶發送XML文件,我應該從這些文件中提取一些信息。 一個重要信息是在base64中編碼的圖像。

xmlxsd文件定義了包含 base64 編碼圖像的元素,如下所示:

   <xs:element name="image" type="xs:base64Binary" nillable="false" minOccurs="0" maxOccurs="unbounded">
      <xs:annotation>
        <xs:documentation xml:lang="en">
          base64 image.
        </xs:documentation>
      </xs:annotation>
    </xs:element> 

在 SSIS 中,我使用XML Source組件來提取元素。 在組件的“輸入和 Output 屬性”中,我將數據類型(在與 base64 圖像元素相關的外部/輸出列中)定義為image [DT_IMAGE]類型。

Q1:選擇這種數據類型讀取base64編碼的圖片是否正確? byte stream [DT_BYTES]還是string [DT_STR]呢?

Next, I passed the output of the component to a Recordset Destination to store the output in an SSIS variable User::xml_image of type Object (I did this because it is possible to have multiple images).

然后將 object 變量傳遞給Script Task ,轉換為DataTable ,我試圖將“假設第一行/圖像”保存到文件系統中。 我使用的代碼如下:

            DataTable table = new DataTable();
            oleAdapter.Fill(table, Dts.Variables["xml_image"].Value);

            Image image;
            BinaryFormatter bf = new BinaryFormatter();
            var ms = new MemoryStream();

            // convert the first image
            bf.Serialize(ms, table.Rows[0]["image"]);
            byte[] bytes = ms.ToArray();

            using (MemoryStream mem = new MemoryStream(bytes))
            {
                mem.Seek(0, SeekOrigin.Begin);
                image = Image.FromStream(mem); // error in this line: Parameter is not valid.
                image.Save("D:\\tepack.jpeg", ImageFormat.Jpeg);
            }

該腳本一直執行,直到調用FromStream方法並失敗並出現以下錯誤:

參數無效。

Q2:如何修復代碼錯誤,並成功保存圖像,考慮上述場景和配置?

A1。 DT_IMAGE 與 DT_BYTES 與 DT_STR

根據定義, base64編碼的二進制文件是 ASCII 字符串數據,因此數據的初始提取可能是DT_STR

那時,您擁有 XML 中的字符,您可以目視檢查以確認是的,我正確地從 XML 中提取了該字段。

下一步是將 base64 編碼反轉或解碼為原始二進制位。

A2。 Image.FromStream 錯誤

我不確定Image class 的來源,但它可能正在嘗試將數據轉換為不同的圖像格式(png 到 jpg 到 bmp 等),但是 memory 中的位已經您需要的位。 您只需要將字節數組寫入磁盤,類似於

https://www.oreilly.com/library/view/c-cookbook/0596003390/ch02s12.html

byte[] imageBytes = Base64DecodeString(bmpAsString);
fstrm = new FileStream(@"C:\winnt_copy.bmp", FileMode.CreateNew, FileAccess.Write);
BinaryWriter writer = new BinaryWriter(fstrm);
writer.Write(imageBytes);
writer.Close( );
fstrm.Close( );

也許在線書籍上的數據類型鏈接注明了數據類型的最大長度,我們看到一個 DT_STR 是 8000 個字符,而 DT_IMAGE/DT_BYTES/DT_TEXT 是 210 萬個單位(字符或字節)。 由於這些都不是 unicode 數據,因此成本存儲成本都相同,但沒有任何表達式語言可以對數據進行操作(null 和長度檢查 IIRC 除外)並且數據查看器將集中在其中,因此可以進行目視檢查具有挑戰性。

jpg 是一種壓縮文件格式 - 他們丟棄數據以減少字節數。 但是 Base64 是反壓縮的,因為它在將危險的二進制字符映射為安全的 ascii 字符時會擴大大小。 因此,除非您知道源圖像非常小,否則您可能會超出 8000 個字符的邊界。

假設通貨膨脹率為 1.3,您看到的最大原始大小約為 5970 字節。 一個 6kb 的 jpg 文件可能很小且質量低下。 例如,此圖像為 5151 字節

A scene from the film Airplane! The automatic pilot, Otto, and Elaine the stewardess are in the cockpit (It's the little room in the front of the plane where the pilots sit, but that's not important right now) smoking

最后的想法當我輸入這個並考慮問題域時,除非你有充分的理由使用數據流,否則我會在這種情況下避免它。 相反,使用腳本任務粉碎 XML。 如果您不必擔心將數據類型擬合到 SSIS 原始類型中,並且您的所有操作都已經是 .NET 腳本操作這一事實,我認為您將遇到更少的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM