none
如何在PictureBox中, 教 Image 存成符合圖像的大小, 而不是整張圖片 RRS feed

  • 問題

  • Hi 版本 : 我產生了 一個Bitmap, 然後將 PictureBox1.Image = Bitmap_Image, 然後在上面畫了一些東西, 怎麼做才能存成剛好符合圖片的檔案呢?

     

     

    謎之音

    2007年9月11日 下午 01:06

解答

所有回覆

  • 在產生 Bitmap 時指定寬與高。

     

    2007年9月11日 下午 04:14
    版主
  •  

    Hi 版大 : 不好意思, 我知道你說的意思, 但我的是想在一張圖畫畫, 畫完在存, 因為我不確定我的大小說, 請版大指導

     

     

     

    謎之音

    2007年9月11日 下午 04:50
  • 那麼請把你的繪圖動作邏輯詳述,你只說這樣我也不知道你該怎樣插入大小指定的地方。

     

    a. 已知所有繪圖動作的座標,那就從座標中找出最大、最小點,決定寬與高。

     

    b. 未知繪圖動作時,紀錄所有經過的點,決定最大、最小點,存檔前開新的 bitmap 指定大小,用 DrawImage 把目前的圖畫到新的指定大小 Image 上去,然後另存新檔。

     

    c. 算是比較簡單但入門門檻比較高的:畫成 emf 圖檔,若 emf 圖檔不指定範圍時,emf 圖檔會自動決定最適大小,這個最適大小會包含系統內建的邊框,邊框的大小一般點線大概是 1 pixel ,文字大概是依照字型大小決定的一行。不過我通常 emf 也會指定大小,避免邊框太大。

    2007年9月12日 上午 02:03
    版主
  • Hi 版大 : 謝謝指導, 我的邏輯動作是

    1. 在PictureBox能夠 畫畫(這點做到了)

    2. 產生 1024x768 的 bitmap, PictureBix.Image = bitmap

    3.我會在 PictureBox畫畫

    4. 我會將 Image存檔, 但是依據實際所畫的圖的大小來存

     

     

     

    麻煩版大

    2007年9月12日 上午 02:12
  • ...

    你是屬於上面 a, b, c 哪類?

    還是 a, b 混和?

    a, b 混和當 b 來處理。

     

    2007年9月12日 上午 02:15
    版主
  • Hi 版大 : 不好意思, 1 - 4是我的鑼輯步驟, 1- 3我都答成了, 第4項, 想請問版大該怎麼做呢?

     

     

     

    謝謝

    2007年9月12日 上午 02:20
  • ...

    你在步驟 4 執行前是否有記錄所有繪圖動作的座標最大值 (屬於 b 類)?或是已知座標最大值 (屬於 a 類)?

     

    2007年9月12日 上午 02:27
    版主
  •  

    Hi 版大 : 我在第4步骤之前已經有算出, 實際圖像的x和y的(最大與最小)值了

     

     

     

    謝謝

    2007年9月12日 上午 02:30
  • 既然你已知最大座標,那 b 不是有說了嗎:

    Code Snippet
    存檔前開新的 bitmap 指定大小,用 DrawImage 把目前的圖畫到新的指定大小 Image 上去,然後另存新檔。

     

     

     

    2007年9月12日 上午 02:42
    版主
  •  

    Hi 版大 : 我照你的說法, 去做是可以抓到剛好的圖片, 但內容是空的, 可否請版大幫我看是那邊出了問題

     

    Dim m_bmp as Bitmap = New Bitmap(width, height)

    m_Graphics = Graphics.FromImage(m_bmp)
     m_Graphics.DrawImage(PictureBox1.Image, 0, 0, width, height)

     

    請版大指導

    2007年9月12日 上午 05:35
  • 不知道。

    因為你的程式沒有達到一個段落,而且來源的 PictureBox.Image 有沒有圖我也不知道。

     

    下面這個是我用來做任意比例縮放的,比例計算可以跳過不看,你可以只看黃色底的,我的 srcImage 就是你的 PictureBox.Image ,最後你在呼叫 bmp.Save(filename, ImageFormat) 即可。

     

    我不知道你畫完圖你的 m_Graphics 有沒有作 Disponse ,因為你貼出來的程式碼太短了,無法有效判讀。

     

    Code Snippet

    Function DrawImageMapping(ByVal strFile As String, ByVal srcRect As System.Drawing.RectangleF, ByVal destRect As System.Drawing.RectangleF, ByVal bmpSize As System.Drawing.SizeF) As Drawing.Image

         Dim srcImage As Drawing.Image = Drawing.Image.FromFile(strFile)

         Dim bmp As New System.Drawing.Bitmap(bmpSize.Width, bmpSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb)

         Dim grfx As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)

         Dim mapRect, modRect As System.Drawing.RectangleF

         Dim ZoomScale As Double

     

         If bmpSize.Width / destRect.Width < bmpSize.Height / destRect.Height Then

              ZoomScale = bmpSize.Width / destRect.Width

              modRect = New System.Drawing.RectangleF(destRect.X, destRect.Top + (bmpSize.Height / ZoomScale - destRect.Height) / 2, bmpSize.Width, destRect.Height / ZoomScale)

         Else

              ZoomScale = bmpSize.Height / destRect.Height

              modRect = New System.Drawing.RectangleF(destRect.Left - (bmpSize.Width / ZoomScale - destRect.Width) / 2, destRect.Y, bmpSize.Width / ZoomScale, destRect.Height)

         End If

     

         mapRect = New System.Drawing.RectangleF((srcRect.Left - modRect.Left) * ZoomScale, (-srcRect.Top + modRect.Top) * ZoomScale, srcRect.Width * ZoomScale, srcRect.Height * ZoomScale)

         grfx.DrawImage(srcImage, mapRect)

         grfx.Dispose()

         srcImage.Dispose()

     

         Return bmp

    End Function

     

     

     

    2007年9月12日 上午 08:04
    版主
  • 上面那個函數用在這個網頁上:

    http://tlcheng.twbbs.org/Tools/ZoomMap/Select.aspx

     

    2007年9月12日 上午 08:15
    版主
  • Hi 版大 : 我在 DrawImage上出了點問題, 狀況是我用DrawImage畫到另一張圖片, 有時bmp的內容是空白, 有時是資料不齊等, 希望版大幫我看一下那邊出了問題, 我把 code貼出來

    Dim Array_ListX As New ArrayList
        Dim Array_ListY As New ArrayList

    滑鼠座標是利用 PixtureBox1.MouseDown and PixtureBox1.MouseMove來抓取座標, 並用

    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseDown

            m_Drawing = True
            m_LastX = e.X
            m_LastY = e.Y       


        End Sub

     

    rivate Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
           

            If m_Drawing = True Then
                ' Draw the new line.

                Array_ListX.Add(e.X)
                Array_ListY.Add(e.Y)
                m_Graphics.DrawLine(Pens.Black, m_LastX, m_LastY, e.X, e.Y)
                ' Display the result.
                PictureBox1.Image = m_Bitmap

                ' Save the latest point.
                m_LastX = e.X
                m_LastY = e.Y

            End If


        End Sub

     

    '產生自訂目的圖

    m_bmp = New Bitmap(width, height)

     

    m_Graphics = Graphics.FromImage(m_bmp)

    PictureBox2.SizeMode = PictureBoxSizeMode.AutoSize
    PictureBox2.Image = m_bmp

     

    m_Graphics.DrawImage(m_Bitmap, minx, miny)

    PictureBox2.Image.Save("C:\1.bmp")

     

    2007年9月12日 下午 05:57
  • 在你畫到另一張圖之前,你原先的 m_Bitmap 所產生的 Graphics 物件有沒有做 Disponse ?

     

    2007年9月13日 上午 05:26
    版主
  • 沒有

     

    2007年9月13日 上午 05:30
  • 沒看到你完整程式碼,不敢確定,但是我先前有碰過 Graphics 沒有做 Disponse 時,會發生 Graphics 動作未實際畫上去。

     

    所以先前我給你的參考函數最後有 grfx.Disponse() ,因為我後來就養成這個習慣了。

     

    你試看看繪圖動作完成後,加上這個看看。

     

    註:包含原始的圖檔以及另存新檔的圖檔。

     

    2007年9月13日 上午 06:25
    版主
  • 已解決了! 謝版大的熱心

     

    2007年9月13日 下午 01:30