2013-11-28 53 views
1

我的Windows Phone應用程序保存由某些文本/數字信息(如圖像捕獲日期等)和一對JPEG圖像組成的對象。C#:保存並加載兩個JPEG圖像到一個文件或從一個文件加載

from byte 0 to 3 -----> INT NUMBER 
from byte 4 to 11 ----> TWO INTs DESCRIBING THE SIZE OF THE NEXT IMAGE 
from byte 12 to X ----> FIRST JPEG IMAGE 
from byte X+1 to X+7 -> TWO INTs DESCRIBING THE SIZE OF THE NEXT IMAGE 
from byte X+8 to Y ---> SECOND JPEG IMAGE 

我已經實現了節省方法是這樣的::

public bool SaveDataToMemory(string filename) 
{ 
    try 
    { 
     IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication(); 
     if (!appStorage.DirectoryExists(App.USER_FOLDER)) 
     { 
      appStorage.CreateDirectory(App.USER_FOLDER); 
     } 

     if (appStorage.FileExists(filename)) 
     { 
      appStorage.DeleteFile(filename); 
     } 

     IsolatedStorageFileStream fs = null; 
     using (fs = appStorage.CreateFile(filename)) 
     { 
      int thumbW = (int)this.thumbnail.PixelWidth; 
      int thumbH = (int)this.thumbnail.PixelHeight; 
      int thumbLength = thumbW * thumbH; 

      int imageW = (int)this.imageSize.Width; 
      int imageH = (int)this.imageSize.Height; 
      int imageLength = imageW * imageH; 

      byte[] byteToWrite; 
      int bufferCount; 

      byteToWrite = BitConverter.GetBytes(DATA_VERSION); // THE FIRST INT NUMBER 
      fs.Write(byteToWrite, 0, byteToWrite.Length); 

      byteToWrite = BitConverter.GetBytes(thumbW); // THE FIRST COUPLE OF INTs 
      fs.Write(byteToWrite, 0, byteToWrite.Length); 
      byteToWrite = BitConverter.GetBytes(thumbH); 
      fs.Write(byteToWrite, 0, byteToWrite.Length); 

      this.thumbnail.SaveJpeg(fs, thumbW, thumbH, 0, 75); // THE FIRST IMAGE (WriteableBitmap) 


      byteToWrite = BitConverter.GetBytes(imageW); // THE SECOND COUPLE OF INTs 
      fs.Write(byteToWrite, 0, byteToWrite.Length); 
      byteToWrite = BitConverter.GetBytes(imageH); 
      fs.Write(byteToWrite, 0, byteToWrite.Length); 

      this.image.SaveJpeg(fs, imageW, imageH, 0, 92); // THE SECOND IMAGE 
     } 

     return true; 
    } 
    catch (Exception ex) 
    { 
     System.Diagnostics.Debug.WriteLine(ex); 
     return false; 
    } 
} 

的方法應該工作,至少有 例如和簡單,單個文件可以由以下數據組成的順序也不例外。 現在的問題是,當我嘗試將它們加載回來。 我按照之前描述的數據順序訪問數據流,我可以用WriteableBitmap.LoadJpeg檢索並查看第一個圖像(縮略圖),但是當我繼續檢索下一個整數時,它們顯示爲0,第二個圖像無法顯示加載例外。

public bool LoadDataFromMemory(string filename) 
{ 
    try 
    { 
     IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication(); 
     IsolatedStorageFileStream fs = null; 

     if (!appStorage.FileExists(filename)) return false; 

     using (fs = appStorage.OpenFile(filename, FileMode.Open)) 
     { 
      if (fs == null) return false; 

      byte[] dataVersionBuf = new byte[sizeof(Int32)]; // FIRST INTEGER 
      fs.Read(dataVersionBuf, 0, dataVersionBuf.Length); 
      int dataVersion = BitConverter.ToInt32(dataVersionBuf, 0); 

      System.Diagnostics.Debug.WriteLine("Data version:" + dataVersion); 

      byte[] thumbSizeBuf = new byte[8]; 
      fs.Read(thumbSizeBuf, 0, thumbSizeBuf.Length); // SIZE OF THE NEXT IMAGE 

      int thumbW = BitConverter.ToInt32(thumbSizeBuf, 0); 
      int thumbH = BitConverter.ToInt32(thumbSizeBuf, 4); 

      this.thumbnail = new WriteableBitmap(thumbW, thumbH); 
      this.thumbnail.LoadJpeg(fs); // FIRST IMAGE 

      // (this prints the correct information) 
      System.Diagnostics.Debug.WriteLine("Loaded thumbnail " + this.thumbnail.PixelWidth + "x" + this.thumbnail.PixelHeight); 

      byte[] leftSizeBuf = new byte[sizeof(Int32) * 2]; 
      fs.Read(leftSizeBuf, 0, leftSizeBuf.Length); // <<--- PROBLEMS READING HERE! 

      int imageW = BitConverter.ToInt32(leftSizeBuf, 0); 
      int imageH = BitConverter.ToInt32(leftSizeBuf, 4); 
      // imageW and imageH are equal to 0!!!! 

      System.Diagnostics.Debug.WriteLine("Loading left " + imageW + "x" + imageH); 

      WriteableBitmap wb = new WriteableBitmap(imageW, imageH); 
      wb.LoadJpeg(fs); // <--- EXCEPTION HERE! 

      return true; 
     } 
    } 
    catch (Exception ex) 
    { 
     System.Diagnostics.Debug.WriteLine(ex); 
     return false; 
    } 
} 

拋出的異常是System.ArgumentException: incorrect parameter。 我是否實施了錯誤的方法將兩個圖像存儲在同一個流/文件中?

回答

0

完成!從Xenolightning的回答開始,首先我將JPEG數據保存到一個單獨的MemoryStream,這樣我可以用MemoryStream.Length得到它的最終長度。 我寫的長度進入IsolatedStorageFileStream作爲一個簡單的整數,並且之後,我寫從以前的MemoryStream的全部內容以MemoryStream.WriteTo().

// preparing thumbnail stream & length 
ms = new MemoryStream(); 
this.thumbnail.SaveJpeg(ms, thumbW, thumbH, 0, 80); 
thumbLength = (int)ms.Length; 

// THUMB FILESIZE 
byteToWrite = BitConverter.GetBytes(thumbLength); 
fs.Write(byteToWrite, 0, byteToWrite.Length); 

// THUMB DATA 
ms.WriteTo(fs); 

當加載後,我第一讀取文件大小的數據塊,則適量與fs.Read()的數據被傳輸到MemoryStream,然後它被轉換爲位圖對象。

// THUMB FILESIZE 
byteToRead = new byte[sizeof(Int32)]; 
fs.Read(byteToRead, 0, byteToRead.Length); 
int thumbSize = BitConverter.ToInt32(byteToRead, 0); 

// GET RAW DATA 
jpegData = new byte[thumbSize]; 
fs.Read(jpegData, 0, thumbSize); 

// CREATE IMAGE OBJECT 
ms = new MemoryStream(jpegData); 
this.thumbnail = new WriteableBitmap(thumbW, thumbH); 
this.thumbnail.LoadJpeg(ms); 
+0

好東西,很高興我能幫上忙。 – Xenolightning

1

這可能是由於WriteableBitmap.LoadJpeg方法中的意外行爲。它可能會超出你的流,這可能會導致你的流的其餘部分處於不可預測的位置。我建議更新格式以添加jpeg的FileSize(以字節爲單位),並從FileStream中取出MemoryStream以傳遞至WriteableBitmap.LoadJpeg

東西線沿線的:(有可能是編譯的問題,我不是在開發機檢查)

//... 
byte[] jpegSizeBytes = new byte[sizeof(Int32)]; // GET THE JPEG SIZE 
fs.Read(jpegSizeBytes , 0, jpegSizeBytes.Length); 
int jpegSize = BitConverter.ToInt32(jpegSizeBytes , 0); 

byte[] jpegData = new byte[jpegSize]; 
fs.Read(jpegData, 0, jpegSize); 

using(var ms = new MemoryStream(jpegData)) 
{ 
    this.thumbnail = new WriteableBitmap(thumbW, thumbH); 
    this.thumbnail.LoadJpeg(ms); // FIRST IMAGE 
} 
//... 

使用相同的技術上面也加載第二圖像。

+0

我明白了,但是...我怎麼能存儲和檢索JPEG尺寸數據字段?在調用this.thumbnail.SaveJpeg()之前添加一個值,對吧?但是在調用該方法之前,我怎麼能知道實際值? – TheUnexpected

+0

而且,順便說一下,LoadJpeg()如何可以自行溢出流?如果這是真的,那是一個巨大的C#bug! – TheUnexpected

+0

當使用'LoadJpeg()'時,沒有讀取字節數的參數。所以這個方法在理論上可以讀取,直到發現錯誤(可能是jpeg數據之後的一個字節),這會導致流被偏移。不看源頭,我們無法推斷出問題。通過'MemoryStream'更安全,因爲'我們'不關心它的位置 – Xenolightning

相關問題