none
請教 bitmap 類最大可以吃多記憶體的圖片檔呢? RRS feed

  • 問題

  • 問題是這樣的? 小弟我最近在處理圖像 遇到一張500多MB的BMP檔

    然後我寫程式碼去把它讀進來 結果都會發生錯誤 程式碼如下

    Dim X as New bitmap("C:\S.bmp")

    判斷應該是bitmap無法支援到這麼大的圖檔 但100多MB的bitmap都還讀的進來

    所以請問各位大大 是不是如我猜測的一樣 bitmap有限制圖片大小? 那各位碰到這個問題 有什麼變通的解法呢?

    2014年3月17日 上午 10:23

解答

  • 學會用二進位存取方式,只讀取檔案中你要的部分,或是依需要到檔案的位置去讀,而不是無限制地去搶劫記憶體。

    以前念書的時候,DOS 才 640 kb ,就是用多少,讀多少,而不是全部載入。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    • 已標示為解答 向恩 2014年3月19日 上午 01:36
    2014年3月18日 上午 11:50

所有回覆

  • 單一物件大小和單一處理序記憶體限制

    請參考 如何增加WinForm執行檔的記憶體限制?

    上文中心冷大最後的回應就是應變的方法.


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2014年3月17日 上午 11:33
    版主
  • [VB2005]PictureBox 的大小限制

    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年3月17日 下午 12:21
  • 那可以請教一下 何謂抽點運算嗎....? 
    2014年3月17日 下午 01:06
  • 為何要開啟 500多MB的BMP檔?
    BMP檔是一種很不節省RAM的圖檔

    如果你要對這麼大的圖檔做運算的話
    應該用C++去寫
    並找第三方的套件來用, 或是當成2進制的檔案來用
    因為就算是GDI也不見得能夠直接處理這麼大的圖檔

    player

    2014年3月17日 下午 01:53
  • google 用引號包起來。

    要不要做抽點,看你的目的。

    抽點的目的是要把大圖顯示在螢幕上,假設你的圖形是 10000x10000 ,但是你螢幕也不過 1000x1000 ,所以你只要每 10 點拿出一點來畫就可以了。

    原理出來後,就是去找縮圖的演算法。

    每 10 點抽一點,這是最簡單快速的方式,但因為容易失真,比如說你是線圖,可能剛好沒抽到線,所以一般會抽臨近幾點去混色,這就可以從縮圖演算法去找。

    既然要抽點,就要去念檔案結構。

    bmp 還簡單,讀完檔頭就可以很容易抓到你要的點。

    jpg 讀完檔頭後,要依據他混色的點數去還原那附近的點,再把目標點拿來畫。

    我有 DOS 年代的2x種圖形檔案格式說明的中文書,你要找這類書可能要到圖書館,不然就得直接唸英文資料。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年3月17日 下午 03:16
  • 補充:

    所以若是你的目的不是為了顯示在螢幕上或列印出來,根本不用做抽點。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年3月17日 下午 03:17
  • 謝謝各位網友的回覆

    首先我有可能會做到抽點 但現在這不是最重要的問題 我現在感興趣的是其實我現在512mb不是最大張的圖

    我到時候最大張的圖檔要讀到程式中去做運算大概會接近到2gb的用量  目前碰到的問題是這個

    我有辦法直接用bitmap 這個類 直接將這麼大容量的圖檔讀進來做運算嗎? 我有看到底下這篇文章的簡介

    現在我讀取超過512mb以上的圖檔無法做運算 是不是我只要設定好 gcAllowVeryLargeObjects 這個東西

    我就能用bitmap去讀取大型的圖檔呢? 我的電腦是x64的  目前也能用.net4.5

    連結的文章資訊:

    (1) 在 .Net 4.0(含) 以前, 不論你的程式是 X86 或 X64, 單一物件最大只能到 2GB (東扣西扣後, 差不多在 1.6 GB 後就會開始出包), 

    參考 64 位元應用程式 ,

    在 .Net 4.5 有個可用的解決方法: gcAllowVeryLargeObjects<gcallowverylargeobjects></gcallowverylargeobjects>

    (2) 如果在 32 位元作業系統上,處理序的最大可用虛擬記憶體區塊小於 64 MB (64 位元作業系統上小於 1 GB),那麼虛擬記憶體不足就可能引發 OOM (在 64 位元作業系統上,應用程式不太可能會發生虛擬記憶體空間不足的情況)。

    參考來源: 勘查記憶體問題

    PS: 你可以依據這篇文的方式去找出原因

    (3) 在 X86 平台上, 整個應用程式大概也只能用到 2GB, 看來也不太合用, 參考 DA0018:以處理序 Managed 記憶體限制執行的 32 位元應用程式

    2014年3月18日 上午 02:33
  • 請愛用 machine-based scalable computing (ex: HPC)...

    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure



    2014年3月18日 上午 05:27
    版主
  • 學會用二進位存取方式,只讀取檔案中你要的部分,或是依需要到檔案的位置去讀,而不是無限制地去搶劫記憶體。

    以前念書的時候,DOS 才 640 kb ,就是用多少,讀多少,而不是全部載入。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    • 已標示為解答 向恩 2014年3月19日 上午 01:36
    2014年3月18日 上午 11:50
  • 大概理解要怎麼實做了 簡單的說程式碼要先從資料流下手吧

    Dim fileContents As Byte()
            fileContents = My.Computer.FileSystem.ReadAllBytes("C:\Big.bmp")

    我直接寫這樣去讀這張bmp 圖檔  如果此張圖片占用的byte陣列數量超過2gb  

    就要啟用gcAllowVeryLargeObjects 這個東西 去處理吧..

    沒設定過這種東西 這個東西是要直接在下面這裡編寫嗎?

    

    2014年3月19日 上午 01:47
  • http://stackoverflow.com/questions/8641888/outofmemoryexception-when-adding-more-items-to-a-very-large-hashsetint32

    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    2014年3月19日 上午 02:40
    版主
  • 奇怪了 我剛測試了一下

     <runtime>
       <gcAllowVeryLargeObjects enabled="true" />
      </runtime>

    將上面這個寫進去還是不能讀超過2G的檔案

    2014年3月19日 上午 08:10
  • 這個是對陣列作用.

    MSDN 說明得很清楚 : <sentencetext xmlns="http://www.w3.org/1999/xhtml">在您的應用程式組態檔中使用這個元素會啟用超過 2 GB 的陣列,但不會變更其他物件大小或陣列大小的限制.</sentencetext>


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。

    2014年3月19日 上午 08:16
    版主
  • 那我現在要怎麼做才能把超過2gb的檔案都讀到記憶體裡?
    2014年3月19日 上午 09:31
  • 用多少,載入多少,用完的就釋放。

    一般以一節區 64kb 為單位。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?


    2014年3月19日 下午 12:52
  • 這篇有寫到 x64 程式記憶體限制的變更

    http://msdn.microsoft.com/zh-tw/library/ms241064(v=vs.110).aspx


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年3月19日 下午 01:10
  • 我現在正在嘗試心冷大大講的作法 用多少讀多少 只不過很納悶的點是


     <runtime>
       <gcAllowVeryLargeObjects enabled="true" />
      </runtime>

    我將這個下面這個寫進去了 

    為什麼遇到2gb的圖檔還是報錯

    我現在對這個東西的理解是 

    Dim fileContents As Byte()

    我啟用了可以將fileContents 這個陣列提升到放2gb資料的記憶體給它

    之後我寫 fileContents = My.Computer.FileSystem.ReadAllBytes("K:\test_2.bmp")

    將這張圖檔所占用的空間通通塞到 fileContents 這個陣列裡 難道不是這樣子理解嗎?

    實在不是很理解下面這句話的意思 現在有問題的難道是

    在您的應用程式組態檔中使用這個元素會啟用超過 2 GB 的陣列,但不會變更其他物件大小或陣列大小的限制

    還是My.Computer.FileSystem.ReadAllBytes 這個指令不能讀超過2GB的東西嗎?


    2014年3月20日 上午 05:56
  • 陣列索引為 Int32 ,所以 Byte() 不能破 2 GB 。


    不精確的問法,就會得到隨便猜的答案;自己都不肯花時間好好描述問題,又何必期望網友會認真回答?

    2014年3月20日 下午 03:06
  • 我手動把Byte陣列能宣告到的最大數目測出來了

    bixmaxvalue=2147483590

    Dim read1(bixmaxvalue) As Byte

    最大只能到2147483590 在大就出錯了 XD

    2014年3月21日 上午 03:30