none
用saveFileDialog儲存圖錯誤 RRS feed

  • 問題

  • 我用它來儲存我在picturebox用gdi+畫出的圖時錯誤,

    執行時這段就出現  "並未將物件參考設定為物件的執行個體"
     
            this.ImageOut.Image.Save(fs,
                System.Drawing.Imaging.ImageFormat.Jpeg);

    我去看執行時我的ImageOut.Image裡是null,可是我畫面上已經有用gdi+畫出的圖了,是為甚麼呢??

    2009年12月2日 上午 01:11

解答

  • 我不太確定你這邊完整的做法是怎樣,所以我不知道你存的圖是哪裡來的。

    畫在記憶體的部分,上面已經講過觀念,所以你存圖的時候,先存 myBitmap ,確認是不是你要的內容。

    是的話,請明確貼出設定 ImageOut.Image = myBitmap 到 ImageOut.Image.Save 間的程式碼,看看是不是把其他東西塞進來了。

    我自己懶的針對 Pen 這類去做處理,我通常是畫完圖後,直接呼叫 GC.Collect 。

    另外,New Bitmap 預設的 32 bits Color ,底色是一種看起來奇怪的透明色 (綠灰色),如果不熟悉,建議你先用 FillRectangle 填滿整張圖,部分看圖軟體會把透明色用黑色顯示,可能會誤導,也請注意。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    • 已標示為解答 2009年12月2日 上午 03:56
    2009年12月2日 上午 02:57
  • Bitmap bmp1, bmp2;

    您可以先宣告,等要用時,再去new PictureBox1和PictureBox2的大小,這時已經載入元件了吧...
    • 已標示為解答 2009年12月2日 上午 10:16
    2009年12月2日 上午 07:26

所有回覆

  • Hi!

    您是怎麼畫在 PictureBox 的 ? 是在記憶體中畫完後給 PictureBox.Image 顯示嗎? 還是其他方式?

    假如不在意解析度的話,也許也可以考慮 CopyFromScreen

    2009年12月2日 上午 01:19
    版主
  • 我是設定一個按鈕按了裡面 ImageOut.Paint += new PaintEventHandler(this.ImageOut_Paint);連到paint事件裡

    然後在事件裡畫圖
    2009年12月2日 上午 01:36
  • 這樣你 Image 圖層還是空的...

    這邊有篇在討論 .Net PictureBox 圖層的文,你可以看看,你是畫裡面最上方的黑色圖層,Image 是藍色虛線框:
    http://tlcheng.spaces.live.com/blog/cns!145419920BFD55A7!4515.entry


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2009年12月2日 上午 01:44
  • 心冷大,他寫說繞路走的方式是等於

    =>我是要用bitmap畫在記憶體裡面,

         畫完後再把ImageOut.Image=myBitmap嗎?

    我剛剛寫了一個小程式用你之前交的方式測試,寫到記憶體裡,

    都可以出來,也可以儲存,可是我儲存的圖都變成全黑的??

    另外想再問一個問題,哪些時候需要Dispose ,畫布和筆也要嗎

    *不好意思問題有點多^^" 麻煩了!!*

    2009年12月2日 上午 02:27
  • 如果你沒有特別的需求,基本上你直接在繪圖動做時,開個 New Bitmap / MetaFile ,把圖形畫進去,再將其指給 PictureBox.Image 即可。

    也就是說,把你 Paint 事件裡面的程式碼獨立出來,加上
    New Bitmap(PictureBox.Client 大小)
    g = System.Drawing.Graphics.FromImage(Bitmap)
    原先 Paint 事件程式碼
    g.Dispose
    PictureBox.Image = Image

    這樣做叫做 記憶體 繪圖 ,既有討論有很多範例:
    http://social.msdn.microsoft.com/Search/zh-TW/?Refinement=112&query=%u8a18%u61b6%u9ad4%20%u7e6a%u5716

    優點:
    1. 一般動作只需要畫一次,可大量節省 GPU 動作
    2. 視窗動作只需要在 Resize 時重繪
    3. 記憶體內繪圖,使用 GPU 資源少,不像 Paint 事件內每行動作每次繪圖
    4. 不用維護 Paint 事件
    5. 圖層分離,可做進一步應用,如 CAD 的隨滑鼠移動的輔助線,底圖在 Bitmap 上,不受 Paint 事件影響

    缺點:
    1. 需增耗一與視窗同大的 bitmap 記憶體 (現在沒人管吧)


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2009年12月2日 上午 02:45
  • 我不太確定你這邊完整的做法是怎樣,所以我不知道你存的圖是哪裡來的。

    畫在記憶體的部分,上面已經講過觀念,所以你存圖的時候,先存 myBitmap ,確認是不是你要的內容。

    是的話,請明確貼出設定 ImageOut.Image = myBitmap 到 ImageOut.Image.Save 間的程式碼,看看是不是把其他東西塞進來了。

    我自己懶的針對 Pen 這類去做處理,我通常是畫完圖後,直接呼叫 GC.Collect 。

    另外,New Bitmap 預設的 32 bits Color ,底色是一種看起來奇怪的透明色 (綠灰色),如果不熟悉,建議你先用 FillRectangle 填滿整張圖,部分看圖軟體會把透明色用黑色顯示,可能會誤導,也請注意。


    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    • 已標示為解答 2009年12月2日 上午 03:56
    2009年12月2日 上午 02:57
  • 心冷大,我圖出來了!!  結果就是底色的問題.

    經過你詳細的講解,我對畫圖有點概念了,感激不盡!!

    *還有一個小問題*
    我看Bitmap 類別的建構函式,

    我在button裡設定picturebox的高度與寬度

    然後在最上面public的地方宣告一個Bitmap bmp = new Bitmap(用picturebox的高度與寬度來定)

    可是在new  Bitmap(用picturebox的高度與寬度來定) 要如何打

    我在括號裡面找部到取得我在button裡設定的picturebox的高度與寬度

    ps.我picturebox有2個

    2009年12月2日 上午 03:56
  • 看不太懂。
    你是說用 PictureBox1 / PictureBox2 ?
    還是說 New System.Drawing.Bitmap(PictureBox1.ClientSize.Width , PictureBox1.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb) ?

    前篇是邏輯,具體依你的需求而定,看你的回應不是就是你已經解決了嗎?
    還是你是打算在共用宣告區宣告?
    bmp 的大小應該是你畫圖時才宣告,還是你有特殊邏輯?有特定邏輯請先說明清楚,才知道你打算幹嘛。
    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2009年12月2日 上午 05:38
  • 前面可以執行是我在Bitmap bmp = new Bitmap(這裡面自己用數字設定高和寬)

    現在是想不自己打設定,而用取得picturebox的高寬

    我bitmap是在共用宣告區宣告,那我有兩個picturebox就宣告2個bitmap吧

    最主要想知道的是new  Bitmap(用picturebox的高度與寬度來定)??

    因為我打Bitmap bmp=New System.Drawing.Bitmap(PictureBox1.ClientSize.Width , PictureBox1.ClientSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)不能會錯誤

    在new bitmap(這裡面只有picturebox)沒有我的 PictureBox1 / PictureBox2 ,

    是因為是在共用宣告區宣告,還沒執行道我picturebox1在button裡設定的高和寬嗎?

    2009年12月2日 上午 06:40
  • Bitmap bmp1, bmp2;

    您可以先宣告,等要用時,再去new PictureBox1和PictureBox2的大小,這時已經載入元件了吧...
    • 已標示為解答 2009年12月2日 上午 10:16
    2009年12月2日 上午 07:26
  • 沒特殊目的的話, bmp1 / bmp2 宣告在繪圖的副程式內即可,減少公用的情形。
    若需公用,一般是依照 Joe Hung 說的方式,因為當你的 PictureBox.Resize 時,bmp1 / bmp2 都要重新宣告大小,所以這種仍然是在繪圖時,再宣告大小。
    論壇是網友平等互助 保證解答請至 微軟技術支援服務
    提問時,錯誤情境描述與錯誤訊息很重要,情境描述包含你做了什麼,預期的結果與實際發生的結果。一個最爛的問法範例:「我的電腦電腦怎麼不能開機?」誰知道你家是不是沒電還是你根本找不到電源鈕。
    2009年12月2日 上午 09:31
  •  我盡然都忘了要用的時候在宣告大小就好,2位大大謝拉!! 
    2009年12月2日 上午 10:22